#!/usr/bin/env python
# encoding: utf-8

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtPrintSupport import QPrinter, QPrintDialog,QPrintPreviewDialog
from PIL import Image
import os
import re
import time
import xlwt
import xlrd
import xlsxwriter
import random
from win32api import GetSystemMetrics

from scipy.interpolate import interp1d

from pyqtgraph import GraphicsLayoutWidget
import numpy as np
import pyqtgraph as pg
# pg.setConfigOption('background', '#EfEfEf')
# pg.setConfigOption('background', '#000000')
# pg.setConfigOption('foreground', 'k')

class GraphWindow(GraphicsLayoutWidget):
    def __init__(self):
        super(GraphWindow, self).__init__()
        font=QFont()
        font.setBold(True)
        font.setPixelSize(15)
        self.label = pg.LabelItem(justify='right')
        self.label.setFont(font)
        self.addItem(self.label,0,1,colspan=1)
        self.tunnelLine = self.addPlot(1,1,colspan=2)

        self.tunnelLine.getAxis("bottom").tickFont = font
        self.tunnelLine.getAxis("left").tickFont = font
        self.scatter = pg.ScatterPlotItem(size=12, pen=pg.mkPen(None), brush=pg.mkBrush(255, 255, 5, 180))
        self.scatter.setData([0],[0])
        self.tunnelLine.addItem(self.scatter)
        self.tunnelLine.setAutoVisible(y=True)
        self.tunnelLine.setTitle('曲线')
        self.data_x = np.array([1,2,3,4,5,6,7,8,9,10])
        self.data_y = np.array([0,5,2,3,3,5,6,7,8,9])

        #  self.curve_master = self.tunnelLine.plot([-100,100],[50,50],pen='r',name='曲线')
        self.data = np.random.normal(size=10)
        # self.curve_zero = self.tunnelLine.plot([0,0],[0,120],pen='w',name='零点位置')
        self.curve= self.tunnelLine.plot([0,0],[0,0],pen=pg.mkPen('b', width=3),name='原始数据曲线')
        self.curve_deal= self.tunnelLine.plot([0,0],[0,0],pen=pg.mkPen('r', width=3),name='数据处理曲线')

        self.curve_left_1 = self.tunnelLine.plot([0],[0], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        self.curve_left_2 = self.tunnelLine.plot([0],[0], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        self.curve_right_1 = self.tunnelLine.plot([0],[0], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        self.curve_right_2 = self.tunnelLine.plot([0],[0], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")

        self.legends = pg.LegendItem()
        self.legends.setParentItem(self.tunnelLine)
        # self.legends.addItem(self.curve_zero,'零点位置')
        # self.legends.addItem(self.curve,'原始曲线')
        # self.legends.addItem(self.curve_deal,'处理曲线')

        # 当前点位显示
        self.pos_scatter = pg.ScatterPlotItem([0],[0],size=10, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 250, 250))
        self.tunnelLine.addItem(self.pos_scatter)
        self.pos_text = pg.TextItem("(0,0)", anchor=(0.5, -1.0),color='b')
        self.tunnelLine.addItem(self.pos_text)

        self.text = pg.TextItem(html='<div style="text-align: center"><span style="color: #FF0;">information</span><br><span style="color: #FFF; font-size: 26pt;">PEAK</span></div>', anchor=(-0.3,0.5), angle=0, border='w', fill=(0, 0, 255, 100))
        self.tunnelLine.addItem(self.text)
        self.text.setPos(200,100)

        self.colorlist = [
            (0,128,64),
            (0,0,255),
            (0,0,160),
            (128,0,128),
            (128,0,255),
            (255,128,0),
            (255,128,128),
            (255,128,255),
            (255,128,192),
            (128,0,0), ]

        #鼠标十字移动
        self.vLine = pg.InfiniteLine(pen=pg.mkPen('b', width=1),angle=90, movable=False)
        self.hLine = pg.InfiniteLine(pen=pg.mkPen('b', width=1),angle=0, movable=False)
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        #鼠标移动绑定
        self.vb = self.tunnelLine.vb
        self.proxy = pg.SignalProxy(self.tunnelLine.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
        # 鼠标坐标显示文本
        self.text_pos = pg.TextItem("(0,0)", anchor=(0.5, -1.0),color='b')
        self.tunnelLine.addItem(self.text_pos)
        self.text_pos.setPos(0,0)
        # 网格显示
        self.tunnelLine.showGrid(x = True, y = True, alpha = 0.7)
        # 坐标显示
        self.tunnelLine.setLabel('left', "相对剂量(%)", units='')
        self.tunnelLine.setLabel('bottom', "距离(mm)", units='')

        self.pdd_result = {}
        self.oar_result = {}
        self.ebeam_result = {}
        # exporter = pg.exporters.ImageExporter(self.tunnelLine)
        # exporter.parameters()['width'] = 100   # (note this also affects height parameter)
        # # save to file
        # exporter.export('fileName.png')

    def update(self):
        self.data[:-1] = self.data[1:]  # shift data in the array one sample left
                                # (see also: np.roll)
        self.data[-1] = np.random.normal()

    def updateRegion(self, window, viewRange):
        rgn = viewRange[0]
        self.region.setRegion(rgn)

    def np_find_nearest(self, array, value):
        idx = (np.abs(array - value)).argmin()
        return idx

    def mouseMoved(self, evt):
        pos = evt[0]  ## using signal proxy turns original arguments into a tuple
        if self.tunnelLine.sceneBoundingRect().contains(pos):
            mousePoint = self.vb.mapSceneToView(pos)
            index = mousePoint.x()
            x = mousePoint.x()
            y = mousePoint.y()
            # self.tunnelLine.setLabel('bottom', "距离(mm)\t\t\t\tx=%s"%mousePoint.x(), units='')
            self.setCursor(Qt.BlankCursor)
            self.vLine.setPos(mousePoint.x())
            self.hLine.setPos(mousePoint.y())
            self.text_pos.setText("(%0.1f,%0.1f)"%(mousePoint.x(),mousePoint.y()))
            self.text_pos.setPos(mousePoint.x(),mousePoint.y())

            idx = self.np_find_nearest(np.array(self.pos_x), x)
            pos_x = self.pos_x[idx]
            pos_y = self.pos_y[idx]
            self.pos_scatter.setData([pos_x],[pos_y])
            self.pos_text.setText("(%0.1f,%0.1f)"%(pos_x,pos_y))
            self.pos_text.setPos(pos_x,pos_y+20)

    def smooth(self,x,y):
        '''曲线平滑: 细分x轴为0.1为最小刻度，通过tck拟合函数进行曲线拟合 '''
        # tck = interpolate.splrep(x, y)
        # xnew = np.arange(x.min(),x.max(),0.1)
        # ynew = interpolate.splev(xnew, tck)

        # ynew = spline(x,y,xnew)
        # func = interpolate.interp1d(x, y, kind='cubi')
        # 利用xnew和func函数生成ynew，xnew的数量等于ynew数量
        xnew = np.arange(x.min(),x.max(),0.1)
        func = interpolate.interp1d(x, y, kind='linear')
        ynew = func(xnew)

        # tck = interpolate.splrep(x, y)
        # xnew = np.arange(x.min(),x.max(),0.1)
        # ynew = interpolate.splev(xnew, tck)
        return xnew,ynew

    def aveFilter(self,y,span):
        '''均值滤波
        span = 5:
        y(1) = y(1)
        y(2) = y(1)+y(2)+y(3)/3
        y(3) = y(1)+y(2)+y(3)+y(4)+y(5)/5
        '''
        # span = 7
        s = 0
        cen = int(span/2)
        for i in range(0,len(y)):
            if i >= cen:
                y_t = y[i-cen:i+cen]
                if len(y)-i<=cen:
                    y[i]= y[i]
                else:
                    y[i]= sum(y_t)/len(y_t)
            elif 0<i<cen :
                s = s+2
                y_t = y[0:s+1]
                y[i]= sum(y_t)/len(y_t)
        return y

    def linearInterpolation(self, x,y,rate):
        '''插值法计算'''
        for i in range(1, len(y)):
            if y[i-1] <= rate < y[i] or y[i-1] >= rate > y[i]:
                k = (y[i] - y[i-1])/(x[i] - x[i-1])
                b = y[i] - k*x[i]
                x_r = (rate - b)/k
                return x_r
        return False

    def find_nearest(self,array,value):
        err = [abs(a-value) for a in array]
        index = err.index(min(err))
        return index

    def getEbeamPdd(self,x,y,raySize):
        '''电子束-pdd测量结果显示

        x: 坐标系x值(O->G方向上的走位坐标)
        y: 坐标位置对应测量剂量率

        计算结果：
            R100: 100%剂量率位置
            R80: 80%剂量率位置
            R50: 50%剂量率位置
            E0: 能量
            RP:
        '''
        # if not isinstance(x, list) or not isinstance(y, list):
            # return False
        # if not len(x) >0 or not len(y) >0:
            # return False
        R100 = x[y.index(max(y))]
        R80 = self.linearInterpolation(x,y,80)
        R50 = self.linearInterpolation(x,y,50)
        E0 = 2.33*R50/10
        # 计算RP
        L_E0 = [1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,50]
        L_RP = [0.505,1.01,1.51,2.02,2.52,3.02,3.52,4.02,4.52,5.02,5.91,6.90,7.89,8.88,9.87,12.3,14.8,19.6,24.6]
        RP = self.linearInterpolation(L_RP,L_E0,E0)
        html = """ <div style="text-align: center">
                    <span style="color: #000000;font-size: 12pt;">R100:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">R80:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">R50:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">E0:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fMev</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">Rp:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fmm</span>
                    <br>
                   </div>
                """%(R100,R80,R50,E0,RP)
        self.ebeam_result = {
            "R100":R100,
            "R80":R80,
            "R50":R50,
            "E0":E0,
            "RP":RP,
            "x":x,
            "y":y,
        }
        # 清空曲线重新绘制
        self.tunnelLine.clear()
        curve= self.tunnelLine.plot(x,y,pen=pg.mkPen('b', width=3),name='原始数据曲线')
        curve_deal= self.tunnelLine.plot(x,y,pen=pg.mkPen('r', width=3),name='数据处理曲线')
        # 最大值
        y_max = max(y)
        x_max = x[y.index(y_max)]
        arrow = pg.ArrowItem(pos=(x_max, y_max), angle=-30)
        text_max = pg.TextItem(html='<div style="text-align: center"><span style="color: #000; font-size: 8pt;">Max(%s,%s)</span></div>'%(x_max,y_max), anchor=(-0.3,0.5), angle=30, border='w', fill=(0, 0, 255, 100))
        text_max.setPos(x_max, y_max)
        self.tunnelLine.addItem(arrow)
        self.tunnelLine.addItem(text_max)
        s1 = pg.ScatterPlotItem([x_max],[y_max],size=10, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 250, 250))
        self.tunnelLine.addItem(s1)

        self.text.setHtml(html)
        self.text.setPos(max(x)*2/3,max(y)*2/3)
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.text_pos)
        self.tunnelLine.addItem(self.text)
        self.tunnelLine.setLimits(xMin=min(x),xMax=max(x)+10,yMin=0,yMax=max(y)+20)
        self.tunnelLine.autoRange()
        # 更新实时移动坐标图
        self.pos_x = x
        self.pos_y = y
        self.tunnelLine.addItem(self.pos_scatter)
        self.tunnelLine.addItem(self.pos_text)

    def getEbeamOar(self,x,y,raySize):
        '''电子束-平坦度测量结果显示

        x: 走位坐标
        y: 对应坐标的百分比剂量率
        raySize: 射野大小

        return：
            设定条件：射野: 10cm*10cm，源皮距: 100cm, 测量深度：最大剂量点位置
            uniform(均整性)：在x,y轴上90%剂量率区域与射野边缘之间的距离不大于10mm,两边计算出来后,求和
            symmetry(对称性)：在90%区域再内推1cm的区域中,对称两个点用最大值与最小值的比值的组成的列表,列表中取最大值
        '''
        if x[0] > 0:
            x = x[::-1]
            y = y[::-1]
        # 左半边x,y
        x_left = x[0:int(len(x)/2)]
        y_left = y[0:int(len(y)/2)]
        # 右半边x,y
        x_right = x[int(len(x)/2):]
        y_right = y[int(len(y)/2):]
        # 左右接近90点的位置
        x_left_90 = x_left[self.find_nearest(y_left,90)]
        x_right_90 = x_right[self.find_nearest(y_right,90)]
        # 射野大小
        visualField = float(re.search(r'([0-9]+)',raySize).group(0))
        # 均整区与射野左边距离
        uniformArea_left_interval =abs(visualField*10/2-abs(x_left_90))
        # 均整区与射野右边距离
        uniformArea_right_interval = abs(visualField*10/2-abs(x_right_90))
        uniform = (uniformArea_left_interval + uniformArea_right_interval)/2
        # 对称区域，90%内推1cm
        symmetryArea = []
        if x_left_90 > 0 and x_right_90 < 0:
            n_xl = self.find_nearest(x_left,x_left_90-10)
            n_xr = self.find_nearest(x_right,x_right_90+10)
            symmetryArea_left = y_left[n_xl:]
            symmetryArea_right = y_right[:n_xr+1]
            symmetryArea = symmetryArea_left + symmetryArea_right
        if x_left_90 < 0 and x_right_90 > 0:
            n_xl = self.find_nearest(x_left,x_left_90+10)
            n_xr = self.find_nearest(x_right,x_right_90-10)
            symmetryArea_left = y_left[n_xl:]
            symmetryArea_right = y_right[:n_xr+1]
            symmetryArea = symmetryArea_left + symmetryArea_right
        if not symmetryArea:
            return
        symmetry_list = []
        for i in range(0, int(len(symmetryArea)/2)):
            if not len(symmetryArea) % 2 ==0 and i == int(len(symmetryArea)/2):
                # symmetryArea列表长度为奇数，中间数不运算
                break
            left = symmetryArea[i]
            right = symmetryArea[len(symmetryArea)-1-i]
            if left >= right:
                symmetry = left/right
            else:
                symmetry = right/left
            symmetry_list.append(symmetry)
        # 曲线显示
        html = """ <div style="text-align: center">
                    <span style="color: #000000;font-size: 12pt;">均整度:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.3fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">对称性:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.3f</span>
                    <br>
                   </div>
                """%(uniform,max(symmetry_list))
        self.oar_result = {
            "x":x,
            "y":y,
            "uniform":uniform,
            "symmetry":symmetry*100,
        }
        # 清空曲线重新绘制
        self.tunnelLine.clear()
        # self.legends.clear() # 这里需要修改源码,方可使用clear()
        x_left_90 = self.linearInterpolation(x_left,y_left,90)
        x_right_90 = self.linearInterpolation(x_right,y_right,90)
        curve= self.tunnelLine.plot(x,y,pen=pg.mkPen('b', width=3),name='原始数据曲线')
        curve_deal= self.tunnelLine.plot(x,y,pen=pg.mkPen('r', width=3),name='数据处理曲线')
        if x_left_90:
            curve_left_1 = self.tunnelLine.plot([x_left_90,x_left_90,x_left_90],[0,90,100], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        if x_right_90:
            curve_right_1 = self.tunnelLine.plot([x_right_90,x_right_90,x_right_90],[0,90,100], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        # 最大值
        # y_max = max(symmetryArea)
        # x_max = x[y.index(y_max)]
        # arrow = pg.ArrowItem(pos=(x_max, y_max), angle=-30)
        # text_max = pg.TextItem(html='<div style="text-align: center"><span style="color: #000; font-size: 8pt;">Max(%s,%s)</span></div>'%(x_max,y_max), anchor=(-0.3,0.5), angle=30, border='w', fill=(0, 0, 255, 100))
        # text_max.setPos(x_max, y_max)
        # self.tunnelLine.addItem(arrow)
        # self.tunnelLine.addItem(text_max)
        # 最小值
        # y_min = min(symmetryArea)
        # x_min = x[y.index(y_min)]
        # arrow = pg.ArrowItem(pos=(x_min, y_min), angle=30)
        # text_min = pg.TextItem(html='<div style="text-align: center"><span style="color: #000; font-size: 8pt;">Min(%s,%s)</span></div>'%(x_min,y_min), anchor=(-0.3,0.5), angle=-30, border='w', fill=(0, 0, 255, 100))
        # text_min.setPos(x_min, y_min)
        # self.tunnelLine.addItem(arrow)
        # self.tunnelLine.addItem(text_min)
        # 最大、小值点
        # s1 = pg.ScatterPlotItem([x_min,x_max],[y_min,y_max],size=10, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 250, 250))
        # self.tunnelLine.addItem(s1)
        # 文本
        self.text.setHtml(html)
        self.text.setPos(-20,20)
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.text_pos)
        self.tunnelLine.addItem(self.text)
        self.tunnelLine.setLimits(xMin=min(x)-10,xMax=max(x)+10,yMin=0,yMax=max(y)+20)
        self.tunnelLine.autoRange()
        # 更新实时移动坐标图
        self.pos_x = x
        self.pos_y = y
        self.tunnelLine.addItem(self.pos_scatter)
        self.tunnelLine.addItem(self.pos_text)

    def getPhotonPdd(self,x,y,raySize):
        ''' 光子-pdd测量结果显示

        x: 坐标系x值(O->G方向上的走位坐标)
        y: 坐标位置对应测量剂量率

        计算结果：
            R100: 100%剂量率位置
            R80: 80%剂量率位置
            R50: 50%剂量率位置
            D0: 0mm深度处剂量率
            D100: 100mm深度处剂量率
            D200: 200mm深度处剂量率
            D200/D100: 200mm深度处剂量率/100mm深度处剂量率
            Enery: 能量
            TPR:
        '''
        # if not isinstance(x, list):
            # return False
        # if not isinstance(y, list):
            # return False
        max_pos = y.index(max(y))
        x_r = x[max_pos:]
        y_r = y[max_pos:]
        R100 = x[max_pos]
        R80 = self.linearInterpolation(x_r,y_r,80)
        R50 = self.linearInterpolation(x_r,y_r,50)
        D200 = y[x.index(200.0)]
        D100 = y[x.index(100.0)]
        D0 = y[x.index(0.0)]
        # D20/D10、TPR计算
        if D100==0:
            return
        if D200==0:
            return
        D = D200/(D100)
        TPR = 2.189-1.308*(1/D)+0.249*(1/D)*(1/D)
        # 线性差值计算 y = k*x + b
        en = [4,6,8,10,14,16,22,30,50]
        D_list  = np.array([0.54,0.58,0.61,0.63,0.65,0.66,0.68,0.69,0.71])
        energy = self.linearInterpolation(en,D_list,D)

        # 曲线显示
        html = """ <div style="text-align: center">
                    <span style="font-size: 12pt;color: #000000;">D0:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2f %%</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">D10:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2f %%</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">D20:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2f %%</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">D20/D10:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2f</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">TPR20/10:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2f</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">R_max:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2fmm</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">R_80:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2fmm</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">R_50:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2fmm</span>
                    <br>
                    <span style="font-size: 12pt;color: #000000;">Energy:</span>
                    <span style="font-size: 12pt;color: #000000;text-align:right">%.2fMeV</span>
                    <br>
                   </div>
                """%(D0,D100,D200,D,TPR,R100,R80,R50,energy)
        self.pdd_result = {
            "D0":D0,
            "D10":D100,
            "D20":D200,
            "D20_D10":D,
            "TPR":TPR,
            "R100":R100,
            "R80":R80,
            "R50":R50,
            "energy":energy,
            "x":x,
            "y":y,
        }
        # 清空曲线重新绘制
        self.tunnelLine.clear()
        curve= self.tunnelLine.plot(x,y,pen=pg.mkPen('b', width=3),name='原始数据曲线')
        curve_deal= self.tunnelLine.plot(x,y,pen=pg.mkPen('r', width=3),name='数据处理曲线')

        # 最大值
        y_max = max(y)
        x_max = x[y.index(y_max)]
        arrow = pg.ArrowItem(pos=(x_max, y_max), angle=-60)
        text_max = pg.TextItem(html='<div style="text-align: center"><span style="color: #000; font-size: 8pt;">Max(%s,%s)</span></div>'%(x_max,y_max), anchor=(0.0,2.0), angle=0, border='w', fill=(0, 0, 255, 100))
        text_max.setPos(x_max, y_max)
        self.tunnelLine.addItem(arrow)
        self.tunnelLine.addItem(text_max)
        s1 = pg.ScatterPlotItem([x_max],[y_max],size=10, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 250, 250))
        self.tunnelLine.addItem(s1)

        self.text.setHtml(html)
        self.text.setPos(max(x)*2/3,max(y)*2/3)
        self.tunnelLine.addItem(self.text)
        self.tunnelLine.addItem(self.text_pos)
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        self.tunnelLine.setLimits(xMin=min(x),xMax=max(x)+10,yMin=0,yMax=max(y)+20)
        self.tunnelLine.autoRange()
        # 更新实时移动坐标图
        self.pos_x = x
        self.pos_y = y
        self.tunnelLine.addItem(self.pos_scatter)
        self.tunnelLine.addItem(self.pos_text)

    def getPhotonOar(self,x,y,conf):
        """光子-平坦度测量

        计算：
            左边阴影: 左边20%~80%剂量率位置之间的距离
            右边阴影: 右边20%~80%剂量率位置之间的距离
            均整区范围：
                        |射野x      | dm(直线测量) | dm(对角线测量)
                        |5<= x <=10 | 1            | 2
                        |10< x <=30 | 0.1          | 0.2
                        |30< x      | 3            | 6

                        根据表格计算均整区：[-(x/2-dm),(x/2-dm)]
                        情况1：直线测量, 射野x=10cm,得出均整区: -4cm~4cm之间的区域
                        情况2：对角线测量, 射野x=10cm,得出均整区: -3cm~3cm之间的区域
            均整度: 均整区内最大剂量率与最小剂量率的比值
            光野重合性: 左右两边50%剂量率位置与射野之间的绝对距离的平均值，以水下5cm处为标准进行等比计算
                        情况1：射野10cm，左边50%剂量率位置为4.2cm,右边边50%剂量率位置为4.1cm, 水深10cm处测量, 源皮距100cm
                                ( (50-42)*(105/110) + (50-41)*(105/110) ) / 2  = 0.8 mm

                              ^ |\
                              | | \
                         100cm| |  \
                              | |   \
                              | | 5cm\
                              | |_____\
                              | |      \
                              | | 10cm  \
                              v |________\
        """

        # 坐标从负方向排列到正方向
        if x[0] > 0:
            x = x[::-1]
            y = y[::-1]
        raySize = conf['ray_size_x']
        direction = conf['direction']
        # 左半边x,y
        x_l = x[0:int(len(x)/2)]
        y_l = y[0:int(len(y)/2)]
        # 右半边x,y
        x_r = x[int(len(x)/2):]
        y_r = y[int(len(y)/2):]
        # 左边最接近20的y的值
        x_l_R20 = self.linearInterpolation(x_l,y_l,20)
        x_l_R50 = self.linearInterpolation(x_l,y_l,50)
        x_l_R80 = self.linearInterpolation(x_l,y_l,80)
        # 右边最接近20的y的值
        x_r_R20 = self.linearInterpolation(x_r,y_r,20)
        x_r_R50 = self.linearInterpolation(x_r,y_r,50)
        x_r_R80 = self.linearInterpolation(x_r,y_r,80)
        # 射野偏移
        # visualField = float(raySize.replace('\n','').split('cm')[0])
        visualField = float(re.search(r'([0-9]+)',raySize).group(0))
        Field_50 = abs(x_r_R50)+abs(x_l_R50)
        halfField = 10*visualField/2
        deepth = float(conf['deepth'][:-2])
        Dev = (abs(abs(x_r_R50)*(105/(100+deepth/10))-halfField)+abs(abs(x_l_R50)*(105/(100+deepth/10))-halfField))/2
        dm = 0 # 单位cm
        if 1<=visualField<=10:
            dm = 1
        if 10<visualField<=30:
            dm = 0.1*visualField
        if 30<visualField:
            dm = 3
        # 对角线需要*2
        if direction == "AB->GT" or direction == "GT->AB" or direction == "AG->BT" or direction == "BT->AG":
            dm = 2*dm
        # 均整区范围
        visual_xl = -(visualField*10/2-dm*10)
        visual_xr = (visualField*10/2-dm*10)
        # x = [-50, -40, -30, ... 30, 40, 50]
        print(visual_xl)
        print(visual_xr)
        uniformArea = []
        for i in range(0, len(x)):
            if visual_xl <= x[i] <=visual_xr:
                uniformArea.append(y[i])
        # 求出均整性(两边视野区域内，最大剂量/最小计量)
        Dmax = max(uniformArea)
        Dmin = min(uniformArea)
        if Dmin == 0:
            return
        # 算出均整度
        flatValue = Dmax/Dmin
        # 均整区对称性
        symmetry = []
        lenth = len(uniformArea)
        for i in range(0,int(lenth/2)):
            l = uniformArea[i]
            r = uniformArea[lenth-1-i]
            if l == 0 or r == 0:
                return
            if l<r:
                symmetry.append(r/l)
            else:
                symmetry.append(l/r)
        # 左边阴影
        left_shadow = abs(abs(x_l_R20)-abs(x_l_R80))
        # 右边阴影
        right_shadow = abs(abs(x_r_R20)-abs(x_r_R80))
        if symmetry:
            sym= max(symmetry)
        else:
            sym= 0
        html = """ <div style="text-align: center">
                    <span style="color: #000000; font-size: 12pt;">光射野重合性:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.1fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">均整度:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">对称性:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">Dmin:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2f%%</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">左半影:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;">右半影:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.2fmm</span>
                    <br>
                   </div>
                """%(Dev,flatValue,sym,Dmin,left_shadow,right_shadow)
        self.oar_result = {
            "Dev":Dev,
            "flatValue":flatValue,
            "sym":sym,
            "Dmin":Dmin,
            "left_shadow":left_shadow,
            "right_shadow":right_shadow,
            "x":x,
            "y":y,
        }
        # 清空曲线重新绘制
        self.tunnelLine.clear()
        if x_l_R20 and x_l_R80:
            curve_left_1 = self.tunnelLine.plot([x_l_R20,x_l_R20,x_l_R20],[0,20,100], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
            curve_left_2 = self.tunnelLine.plot([x_l_R80,x_l_R80,x_l_R80],[0,80,100], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        if x_r_R20 and x_r_R80:
            curve_right_1= self.tunnelLine.plot([x_r_R20,x_r_R20,x_r_R20],[0,20,100], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
            curve_right_2= self.tunnelLine.plot([x_r_R80,x_r_R80,x_r_R80],[0,80,100], pen=(0,200,200), symbolBrush=(0,0,200), symbolPen='w', symbol='o', symbolSize=8, name="symbol='o'")
        curve= self.tunnelLine.plot(x,y,pen=pg.mkPen('b', width=3),name='原始数据曲线')
        curve_deal= self.tunnelLine.plot(x,y,pen=pg.mkPen('r', width=3),name='数据处理曲线')

        # 最大值
        # x_max = x[y.index(Dmax)]
        # arrow = pg.ArrowItem(pos=(x_max, Dmax), angle=-30)
        # text_max = pg.TextItem(html='<div style="text-align: center"><span style="color: #000; font-size: 8pt;">Max(%s,%s)</span></div>'%(x_max,Dmax), anchor=(-0.3,0.5), angle=30, border='w', fill=(0, 0, 255, 100))
        # text_max.setPos(x_max, Dmax)
        # self.tunnelLine.addItem(arrow)
        # self.tunnelLine.addItem(text_max)
        # 最小值
        # x_min = x[y.index(Dmin)]
        # arrow = pg.ArrowItem(pos=(x_min, Dmin), angle=30)
        # text_min = pg.TextItem(html='<div style="text-align: center"><span style="color: #000; font-size: 8pt;">Min(%s,%s)</span></div>'%(x_min,Dmin), anchor=(-0.3,0.5), angle=-30, border='w', fill=(0, 0, 255, 100))
        # text_min.setPos(x_min, Dmin)
        # self.tunnelLine.addItem(arrow)
        # self.tunnelLine.addItem(text_min)
        # 最大、小值点
        # s1 = pg.ScatterPlotItem([x_min,x_max],[Dmin,Dmax],size=10, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 250, 250))
        # self.tunnelLine.addItem(s1)

        self.text.setHtml(html)
        self.text.setPos(-20,20)
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.text_pos)
        self.tunnelLine.addItem(self.text)
        self.tunnelLine.setLimits(xMin=min(x)-10,xMax=max(x)+10,yMin=0,yMax=max(y)+20)
        self.tunnelLine.autoRange()

        # 更新实时移动坐标图
        self.pos_x = x
        self.pos_y = y
        self.tunnelLine.addItem(self.pos_scatter)
        self.tunnelLine.addItem(self.pos_text)

    def pddPlotHistory(self,x,y,raySize,testType,rayType):
        'pdd曲线显示'
        if not isinstance(x, list):
            return False
        if not isinstance(y, list):
            return False
        if x and y:
            x = np.array(x)
            y = np.array(y)
            xnew = x
            ynew = y
            self.tunnelLine.setXRange(x.min(),x.max())
            self.tunnelLine.setYRange(y.min(),y.max())
            self.datax = xnew
            self.datay = ynew
            self.curve_master.setData(xnew,ynew)
            try:
                D,y100_position,y80_position,y50_position = self.getPdd(xnew,ynew)
                html = self.pddHtml(D,y100_position,y80_position,y50_position,testType,rayType,raySize)
                self.text.setHtml(html)
                self.text.setPos(0,y.max()/3)
            except:
                pass

    def multiLine(self,x,y,c):
        '''多条曲线显示'''
        self.tunnelLine.clear()
        colorlist = [
            (0,128,64),
            (0,0,255),
            (0,0,160),
            (128,0,128),
            (128,0,255),
            (255,128,0),
            (255,128,128),
            (255,128,255),
            (255,128,192),
            (128,0,0), ]

        for i in range(0,len(x)):
            curve= self.tunnelLine.plot(x[i],y[i],pen=colorlist[random.randint(0,9)])
            self.legends.addItem(curve,c[i])
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        return

class TreeWidget(QTreeWidget):
    def __init__(self, parent = None):
        super(TreeWidget, self).__init__(parent)
        self.setColumnCount(1)
        # 设置多选
        self.setSelectionMode(QAbstractItemView.ExtendedSelection)
        # 取消拖拽功能
        self.setAcceptDrops(False)

    def addDataItem(self, file_list):
        item = QTreeWidgetItem(['data'])
        item.setIcon(0,QIcon(':icons/images_rc/data.png'))
        for f in file_list:
            data_item = QTreeWidgetItem([str(f)])
            data_item.setIcon(0,QIcon(':icons/images_rc/data.png'))
            item.addChild(data_item)
        self.addTopLevelItem(item)


class tabView(QTableView):
    def __init__(self, parent=None):
        '''表格初始化'''
        super(tabView, self).__init__(parent)
        self.model = QStandardItemModel(0, 0)
        self.HeaderList = ['x(mm)','y(mm)','z(mm)','主测通道(cGy/min)','监测通道(cGy/min)','修正','归一化']
        self.model.setHorizontalHeaderLabels(self.HeaderList)#
        self.setModel(self.model)
        #下面代码让表格100填满窗口
        self.horizontalHeader().setStretchLastSection(True)
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.isClearChooseLine_Flag = False
        #  self.setMaximumHeight(250)

        self.clear_data()
        # 右键菜单设置
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.right_menu)

    def right_menu(self):
        self.menu = QMenu()
        exportAction = QAction("&导出excel",triggered=self.exportToExcel)
        self.menu.addAction(exportAction)
        self.menu.exec(QCursor.pos())

    def clear_data(self):
        self.model.clear()
        self.model = QStandardItemModel(0, 0)
        self.model.setHorizontalHeaderLabels(self.HeaderList)#
        self.setModel(self.model)

    def add_data(self,x,y,z,t1,t2):
        rowNum = self.model.rowCount()  # 总行数
        t = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        self.model.setItem(rowNum, 0, QStandardItem(str(t)))
        self.model.setItem(rowNum, 1, QStandardItem(str(x)))
        self.model.setItem(rowNum, 2, QStandardItem(str(y)))
        self.model.setItem(rowNum, 3, QStandardItem(str(z)))
        self.model.setItem(rowNum, 4, QStandardItem(str(t1)))
        self.model.setItem(rowNum, 5, QStandardItem(str(t2)))

    def exportToExcel(self):
        f = QFileDialog.getSaveFileName(self,"导出Excel",'%s/data'%os.getcwd(),'Excel Files(*.xls)')
        if f[0]:
            try:
                filename = f[0]
                wb = xlwt.Workbook()
                ws = wb.add_sheet('sheet1')#sheetname
                data = []
                data.append(self.HeaderList)
                row = self.model.rowCount()
                col = self.model.columnCount()
                for r in range(0, row):
                    data.append([float(self.model.data(self.model.index(r, c))) for c in range(col)])
                for i in range(0,len(data)):
                    for j in range(0,len(data[i])):
                        ws.write(i, j, data[i][j])
                wb.save(filename)
                QMessageBox.warning(self,'提示','导出成功!\r\n%s'%filename,QMessageBox.Yes)
            except:
                QMessageBox.warning(self,'警告','文件被占用，无法导出!',QMessageBox.Yes)

    def exportToFile(self,task):
        '''计算pdd或oar重复性和归一化，
        并导出表格数据为.pdd文件或.oar文件'''
        t = task
        taskinfo = ''
        filename= ''
        row = self.model.rowCount()
        Tm = []
        Ts = []
        x = []
        y = []
        z = []
        for r in range(0,row):
            x.append(float(self.model.data(self.model.index(r,1))))
            y.append(float(self.model.data(self.model.index(r,2))))
            z.append(float(self.model.data(self.model.index(r,3))))
            Tm.append(float(self.model.data(self.model.index(r,4))))
            Ts.append(float(self.model.data(self.model.index(r,5))))
        #　计算重复性
        Repeat  = [float('%.4f'%(Tm[i]/(Ts[i]+0.00001))) for i in range(0,row)]
        #　计算归一化
        normal = None
        timetest = time.strftime("%Y:%m:%d-%H:%M:%S", time.localtime())
        if t['tasktype']== 'pdd':
            dR_max = max(Repeat)
            normal = [float('%.4f'%(Repeat[i]/dR_max)) for i in range(0,row)]
            taskinfo='测试类型:%s\r\n能量:%s\r\n射线:%s\r\nSSD:%s\r\n射野尺寸:%s\r\n深度:%s\r\n步距:%s\r\n\r\n坐标移动:%s-->%s'%(
                t['tasktype'],t['power'],t['rayType'],t['ssd'],t['raySize'],t['distance'],t['step'],t['directionAxis'][0],t['directionAxis'][1])
            filename = '%s__%s__%s__%s__.pdd'%(timetest,t['rayType'],t['power'],t['raySize'])
        if t['tasktype']== 'oar':
            dR_zero = Repeat[y.index(0)]
            normal = [float('%.4f'%(Repeat[i]/dR_zero)) for i in range(0,row)]
            taskinfo = '测试类型:%s\r\n能量:%s\r\n射线:%s\r\nSSD:%s\r\n测试深度:%s\r\n射野尺寸:%s\r\n射野步距:%s\r\n边缘距离:%s\r\n边缘步距:%s\r\n\r\n方向:%s\r\n坐标移动:%s-->%s'%(
                t['tasktype'],t['power'],t['rayType'],t['ssd'],t['deepth'],t['raySize'],t['rayStep'],t['edgeFiled'],t['edgeStep'],t['direction'],t['directionAxis'][0],t['directionAxis'][1])
            filename = '%s__%s__%s__%s__.oar'%(timetest,t['rayType'],t['power'],t['raySize'])
        for i in range(0,row):
            self.model.setItem(i, 6, QStandardItem(str(Repeat[i])))
            self.model.setItem(i, 7, QStandardItem(str(normal[i])))
        data = ''
        for r in range(0,row):
            t='%s,%s,%s,%s,%s,%s,%s,%s'%(
                self.model.data(self.model.index(r,0)),
                self.model.data(self.model.index(r,1)),
                self.model.data(self.model.index(r,2)),
                self.model.data(self.model.index(r,3)),
                self.model.data(self.model.index(r,4)),
                self.model.data(self.model.index(r,5)),
                self.model.data(self.model.index(r,6)),
                self.model.data(self.model.index(r,7)))
            data = data+t+'\r\n'
        timetest = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        inf =   '测试时间:%s\r\n'%timetest+\
                'Data Begin:\r\n\r\n'+\
                '数据个数:%s\r\n'%row+\
                'T,X,Y,Z,主测,监测,修正,归一化\r\n'+\
                '%s\r\n'%data+\
                'Data End\r\n'+\
                '\r\n%s\r\n'%taskinfo
        with open('pddoar/%s'%filename, 'w') as f:
            f.write(inf)

    def add_excel_data(self,data):
        self.clear_data()
        for j in range(0,len(data)):
            for i in range(0,len(data[j])):
                self.model.setItem(i, j, QStandardItem(str(data[j][i])))

    def addData(self,data):
        self.clear_data()
        for i in range(0,len(data)):
            for j in range(0,len(data[i])):
                self.model.setItem(j, i, QStandardItem(str(data[i][j])))

    def addDataRow(self, data):
        self.clear_data()
        for i in range(0,len(data)):
            for j in range(0,len(data[i])):
                self.model.setItem(i, j, QStandardItem(str(data[i][j])))

    def get_standard(self,x,ave):
        import math
        n = len(x)
        s = 0
        for i in range(0,n):
            s = s+pow((int(x[i])-ave),2)
        s = math.sqrt(1/(n-1)*s)
        return s

    def get_data(self):
        rowNum = self.model.rowCount()  # 总行数
        x = [self.model.data(self.model.index(i, 1)) for i in range(0,rowNum)]
        line1 = [self.model.data(self.model.index(i, 4)) for i in range(0,rowNum)]
        line2 = [self.model.data(self.model.index(i, 5)) for i in range(0,rowNum)]
        return (x,line1,line2)

    def get_all_data(self):
        rowNum = self.model.rowCount()  # 总行数
        colNum = self.model.columnCount()  # 总行数
        data = []
        for j in range(0,colNum):
            col = [self.model.data(self.model.index(i, j)) for i in range(0,rowNum)]
            data.append(col)
        return data

    def get_data_by_col(self):
        rowNum = self.model.rowCount()  # 总行数
        colNum = self.model.columnCount()  # 总行数
        data = []
        for c in range(0,colNum):
            item = [self.model.data(self.model.index(r, c)) for r in range(0,rowNum)]
            data.append(item)
        return data

    def get_data_by_row(self):
        rowNum = self.model.rowCount()  # 总行数
        colNum = self.model.columnCount()  # 总行数
        data = []
        for r in range(0,rowNum):
            item = [self.model.data(self.model.index(r, c)) for c in range(0, colNum)]
            data.append(item)
        return data

class GraphWidget(GraphicsLayoutWidget):
    pos_x = [0,1,2,3,4,5]
    pos_y = [0,0,0,0,0,0]
    conf = None
    original_x = [0,1,2,3,4,5]
    original_y = [0,0,0,0,0,0]
    signal_result = pyqtSignal(str)
    signal_result_update = pyqtSignal(dict)
    result = {}
    def __init__(self):
        super(GraphWidget, self).__init__()
        # 添加文本显示坐标等信息
        self.label = pg.LabelItem(justify='right')
        self.addItem(self.label)
        # 添加图表plot
        self.plot = self.addPlot(row=1,col=0,colspan=2)
        # 图表标题设置
        self.plot.setTitle('曲线')
        # 图表显示字体设置
        font=QFont()
        font.setBold(True)
        font.setPixelSize(15)
        self.plot.getAxis("bottom").tickFont = font
        self.plot.getAxis("left").tickFont = font
        self.plot.setAutoVisible(y=True)
        # 图表网格显示
        self.plot.showGrid(x = True, y = True, alpha = 0.7)
        # 图表坐标显示
        self.plot.setLabel('left', "相对剂量(%)", units='')
        self.plot.setLabel('bottom', "距离(mm)", units='')
        # 添加曲线
        self.curve= self.plot.plot(self.pos_x,self.pos_y,pen=pg.mkPen('r', width=2),name='测量曲线')
        self.mirror_curve = None
        # 数据点显示
        self.scatter = pg.ScatterPlotItem(size=3, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 255, 180))
        self.scatter.setData(self.pos_x,self.pos_y)
        self.plot.addItem(self.scatter)
        # 实时位置点显示
        self.pos_scatter = pg.ScatterPlotItem([0],[0],size=10, pen=pg.mkPen(None), brush=pg.mkBrush(0, 0, 250, 250))
        self.plot.addItem(self.pos_scatter)
        # 鼠标十字移动
        self.vLine = pg.InfiniteLine(pen=pg.mkPen('b', width=1),angle=90, movable=False)
        self.hLine = pg.InfiniteLine(pen=pg.mkPen('b', width=1),angle=0, movable=False)
        self.plot.addItem(self.vLine, ignoreBounds=True)
        self.plot.addItem(self.hLine, ignoreBounds=True)
        # 鼠标移动绑定
        self.vb = self.plot.vb
        self.proxy = pg.SignalProxy(self.plot.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)

    def np_find_nearest(self, array, value):
        idx = (np.abs(array - value)).argmin()
        return idx

    def mouseMoved(self, evt):
        pos = evt[0]  ## using signal proxy turns original arguments into a tuple
        if self.plot.sceneBoundingRect().contains(pos):
            try:
                mousePoint = self.vb.mapSceneToView(pos)
                index = mousePoint.x()
                x = mousePoint.x()
                y = mousePoint.y()
                self.setCursor(Qt.BlankCursor)
                self.vLine.setPos(x)
                self.hLine.setPos(y)

                idx = self.np_find_nearest(np.array(self.pos_x), x)
                pos_x = self.pos_x[idx]
                pos_y = self.pos_y[idx]

                self.pos_scatter.setData([pos_x],[pos_y])

                txt_mouse = '''<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y=%0.1f</span>''' % (x, y)
                txt_pos = '''<span style='font-size: 12pt'>x=%0.1f, <span style='color: red'>y=%0.1f</span>''' % (pos_x, pos_y)
                self.label.setText("移动坐标:%s, 点位坐标:%s"%(txt_mouse, txt_pos))
            except:
                pass

    def samePlot(self, x, y_l, y_r, conf):
        self.plot.setLabel('left', "位置(mm)", units='')
        self.plot.setLabel('bottom', "深度(mm)", units='')
        self.original_x = x
        self.original_y = y_l
        self.conf = conf
        self.pos_x = x
        self.pos_y = y_l
        self.lineOriginal()

    def updatePos(self, x, y, conf):
        self.original_x = x
        self.original_y = y
        self.conf = conf
        self.pos_x = x
        self.pos_y = y
        # self.scatter.setData(x,y)
        # self.curve.setData(x,y)
        self.lineOriginal()

    def lineOriginal(self):
        """原始曲线"""
        self.pos_x = self.original_x
        self.pos_y = self.original_y
        self.scatter.setData(self.pos_x, self.pos_y)
        self.curve.setData(self.pos_x, self.pos_y)
        self.getResult()

        if self.mirror_curve:
            self.plot.removeItem(self.mirror_curve)
            self.mirror_curve = None

    def lineShiftLeft(self, val):
        """曲线左移"""
        if isinstance(val, float):
            # self.pos_x = self.original_x
            # self.pos_y = self.original_y
            self.pos_x = [x-val for x in self.pos_x]
            self.scatter.setData(self.pos_x, self.pos_y)
            self.curve.setData(self.pos_x, self.pos_y)
            self.getResult()

    def lineShiftRight(self, val):
        """曲线右移"""
        if isinstance(val, float):
            # self.pos_x = self.original_x
            # self.pos_y = self.original_y
            self.pos_x = [x+val for x in self.pos_x]
            self.scatter.setData(self.pos_x, self.pos_y)
            self.curve.setData(self.pos_x, self.pos_y)
            self.getResult()

    def lineSmooth(self):
        """曲线平滑"""
        # self.pos_x = self.original_x
        # self.pos_y = self.original_y
        x = np.array(self.pos_x)
        y = np.array(self.pos_y)
        self.pos_x = np.arange(min(x),max(x),0.1)
        # func = interp1d(x, y, kind='linear')
        func = interp1d(x, y, kind='quadratic')
        # print(self.pos_x)
        # print(self.pos_x)
        self.pos_y = func(self.pos_x)
        self.scatter.setData(x, y)
        self.curve.setData(self.pos_x, self.pos_y)
        self.getResult()

    def lineEquidistant(self, val):
        """曲线等距补点"""
        if isinstance(val, float):
            if val > 0:
                try:
                    self.pos_x = self.original_x
                    self.pos_y = self.original_y
                    x = np.array(self.pos_x)
                    y = np.array(self.pos_y)
                    self.pos_x = np.arange(min(x),max(x),val)
                    func = interp1d(x, y, kind='linear')
                    self.pos_y = func(self.pos_x)
                    self.scatter.setData(self.pos_x, self.pos_y)
                    self.curve.setData(self.pos_x, self.pos_y)
                    self.getResult()
                except:
                    QMessageBox.information(self,'错误','等距参数设置错误，参数超出间隔！',QMessageBox.Yes)

    def lineSymmetry(self):
        """曲线对称"""

    def lineMirror(self):
        """镜像"""
        if self.mirror_curve:
            self.plot.removeItem(self.mirror_curve)
            self.mirror_curve = None
        else:
            x_new = self.pos_x
            y_new = self.pos_y[::-1]
            self.mirror_curve= self.plot.plot(x_new,y_new,pen=pg.mkPen('g', width=2),name='镜像曲线')

    def lineZoomAdd(self):
        """放大"""

    def lineZoomDec(self):
        """缩小"""

    def lineZoomOne(self):
        """1:1正常显示"""

    def aveFilter(self,y,span):
        '''均值滤波
        span = 5:
        y(1) = y(1)
        y(2) = y(1)+y(2)+y(3)/3
        y(3) = y(1)+y(2)+y(3)+y(4)+y(5)/5
        '''
        # span = 7
        s = 0
        cen = int(span/2)
        for i in range(0,len(y)):
            if i >= cen:
                y_t = y[i-cen:i+cen]
                if len(y)-i<=cen:
                    y[i]= y[i]
                else:
                    y[i]= sum(y_t)/len(y_t)
            elif 0<i<cen :
                s = s+2
                y_t = y[0:s+1]
                y[i]= sum(y_t)/len(y_t)
        return y

    def linearInterpolation(self, x,y,rate):
        '''插值法计算'''
        for i in range(1, len(y)):
            if y[i-1] < rate < y[i] or y[i-1] > rate > y[i]:
                k = (y[i] - y[i-1])/(x[i] - x[i-1])
                b = y[i] - k*x[i]
                x_r = (rate - b)/k
                return x_r
        return False

    def find_nearest(self, array, value):
        err = [abs(a-value) for a in array]
        index = err.index(min(err))
        return index

    def multiLine(self,x,y,c):
        '''多条曲线显示'''
        self.tunnelLine.clear()
        colorlist = [
            (0,128,64),
            (0,0,255),
            (0,0,160),
            (128,0,128),
            (128,0,255),
            (255,128,0),
            (255,128,128),
            (255,128,255),
            (255,128,192),
            (128,0,0), ]

        for i in range(0,len(x)):
            curve= self.tunnelLine.plot(x[i],y[i],pen=colorlist[random.randint(0,9)])
            self.legends.addItem(curve,c[i])
        self.tunnelLine.addItem(self.vLine, ignoreBounds=True)
        self.tunnelLine.addItem(self.hLine, ignoreBounds=True)
        return

    def getResult(self):
        conf = self.conf
        x = np.array(self.pos_x)
        y = np.array(self.pos_y)
        xnew = np.array(self.pos_x)
        ynew = np.array(self.pos_y)

        # xnew = np.arange(min(x),max(x)+1,1)
        # func = interp1d(x, y, kind='linear')
        # ynew = func(xnew)
        if conf['type'] == 'OAR':
            self.getOar(xnew,ynew,conf)
        if conf['type'] == 'PDD':
            self.getPdd(xnew,ynew,conf)
        # if conf['ray_type'] == '电子':
            # raySize = conf['ray_size_x']
            # raySize = float(re.search(r'([0-9]+)',raySize).group(0))
            # if conf['type'] == 'OAR':
                # self.getEbeamOar(xnew,ynew, raySize)
            # if conf['type'] == 'PDD':
                # self.getEbeamPdd(xnew,ynew, raySize)
        # if conf['ray_type'] == '光子':
            # if conf['type'] == 'OAR':
                # self.getPhotonOar(xnew,ynew,conf)
            # if conf['type'] == 'PDD':
                # self.getPhotonPdd(xnew,ynew,conf)
        # if conf['ray_type'] == 'Co60':
            # if conf['type'] == 'OAR':
                # self.getCo60Oar(xnew,ynew,conf)
            # if conf['type'] == 'PDD':
                # self.getCo60Pdd(xnew,ynew,conf)
        self.plot.autoRange()

    def getEbeamOar(self,x,y,raySize):
        '''电子束-平坦度测量结果显示

        x: 走位坐标
        y: 对应坐标的百分比剂量率
        raySize: 射野大小

        return：
            设定条件：射野: 10cm*10cm，源皮距: 100cm, 测量深度：最大剂量点位置
            uniform(均整性)：在x,y轴上90%剂量率区域与射野边缘之间的距离不大于10mm,两边计算出来后,求和
            symmetry(对称性)：在90%区域再内推1cm的区域中,对称两个点用大值与小值的比值的组成的列表,列表中取最大值
        '''
        if x[0] > 0:
            x = x[::-1]
            y = y[::-1]
        y_max = max(y)
        # 左半边x,y
        x_l = x[0:int(len(x)/2)]
        y_l = y[0:int(len(y)/2)]
        # 右半边x,y
        x_r = x[int(len(x)/2):]
        y_r = y[int(len(y)/2):]

        x_l_20 = self.linearInterpolation(x_l,y_l,20)
        x_l_50 = self.linearInterpolation(x_l,y_l,50)
        x_l_80 = self.linearInterpolation(x_l,y_l,80)
        x_l_90 = self.linearInterpolation(x_l,y_l,90)

        x_r_20 = self.linearInterpolation(x_r,y_r,20)
        x_r_50 = self.linearInterpolation(x_r,y_r,50)
        x_r_80 = self.linearInterpolation(x_r,y_r,80)
        x_r_90 = self.linearInterpolation(x_r,y_r,90)

        # 左半影
        shadow_l = abs(abs(x_l_20)-abs(x_l_80))
        # 右半影
        shadow_r = abs(abs(x_r_20)-abs(x_r_80))

        # 电子束测量均整区计算
        uniform = (abs(raySize*10/2-abs(x_l_90)) + abs(raySize*10/2-abs(x_r_90))) / 2

        # 电子束对称区域，90%内推1cm
        symmetryArea = []
        if x_l_90 > 0 and x_r_90 < 0:
            n_xl = self.find_nearest(x_l,x_l_90-10)
            n_xr = self.find_nearest(x_r,x_r_90+10)
            symmetryArea_left = y_l[n_xl:]
            symmetryArea_right = y_r[:n_xr+1]
            symmetryArea = np.append(symmetryArea_left, symmetryArea_right)
        if x_l_90 < 0 and x_r_90 > 0:
            n_xl = self.find_nearest(x_l,x_l_90+10)
            n_xr = self.find_nearest(x_r,x_r_90-10)
            symmetryArea_left = y_l[n_xl:]
            symmetryArea_right = y_r[:n_xr+1]
            symmetryArea = np.append(symmetryArea_left, symmetryArea_right)
        if len(symmetryArea) == 0:
            return False

        symmetry_list = []
        for i in range(0, int(len(symmetryArea)/2)):
            if not len(symmetryArea) % 2 ==0 and i == int(len(symmetryArea)/2):
                # symmetryArea列表长度为奇数，中间数不运算
                break
            left = symmetryArea[i]
            right = symmetryArea[len(symmetryArea)-1-i]
            if left >= right:
                symmetry = left/right
            else:
                symmetry = right/left
            symmetry_list.append(symmetry)
        # 曲线显示
        html = """ <div>
                    <span style="color: #000000;font-size: 12pt;float:left">均整度:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.3fmm</span>
                    <br>
                    <span style="color: #000000;font-size: 12pt;float:left">对称性:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.3f</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">左半影:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">右半影:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">Dmax:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.3f%%</span>
                    <br>
                   </div>
                """%(uniform,max(symmetry_list), shadow_l, shadow_r, y_max)
        self.signal_result.emit(html)
        self.result = {
            "x":x,
            "y":y,
            "uniform":uniform,
            "symmetry":symmetry*100,
        }
        self.signal_result_update.emit(self.result)

    def getPhotonOar(self,x,y,conf):
        """光子-平坦度测量

        计算：
            左边阴影: 左边20%~80%剂量率位置之间的距离
            右边阴影: 右边20%~80%剂量率位置之间的距离
            均整区范围：
                        |射野x      | dm(直线测量) | dm(对角线测量)
                        |5<= x <=10 | 1            | 2
                        |10< x <=30 | 0.1          | 0.2
                        |30< x      | 3            | 6

                        根据表格计算均整区：[-(x/2-dm),(x/2-dm)]
                        情况1：直线测量, 射野x=10cm,得出均整区: -4cm~4cm之间的区域
                        情况2：对角线测量, 射野x=10cm,得出均整区: -3cm~3cm之间的区域
            均整度: 均整区内最大剂量率与最小剂量率的比值
            光野重合性: 左右两边50%剂量率位置与射野之间的绝对距离的平均值，以水下5cm处为标准进行等比计算
                        情况1：射野10cm，左边50%剂量率位置为4.2cm,右边边50%剂量率位置为4.1cm, 水深10cm处测量, 源皮距100cm
                                ( (50-42)*(105/110) + (50-41)*(105/110) ) / 2  = 0.8 mm

                              ^ |\
                              | | \
                         100cm| |  \
                              | |   \
                              | | 5cm\
                              | |_____\
                              | |      \
                              | | 10cm  \
                              v |________\
        """

        # 坐标从负方向排列到正方向
        if x[0] > 0:
            x = x[::-1]
            y = y[::-1]
        raySize = conf['ray_size_x']
        direction = conf['direction']
        # 左半边x,y
        x_l = x[0:int(len(x)/2)]
        y_l = y[0:int(len(y)/2)]
        # 右半边x,y
        x_r = x[int(len(x)/2):]
        y_r = y[int(len(y)/2):]
        # 左边最接近20的y的值
        x_l_R20 = self.linearInterpolation(x_l,y_l,20)
        x_l_R50 = self.linearInterpolation(x_l,y_l,50)
        x_l_R80 = self.linearInterpolation(x_l,y_l,80)
        # 右边最接近20的y的值
        x_r_R20 = self.linearInterpolation(x_r,y_r,20)
        x_r_R50 = self.linearInterpolation(x_r,y_r,50)
        x_r_R80 = self.linearInterpolation(x_r,y_r,80)
        # 射野偏移
        # visualField = float(raySize.replace('\n','').split('cm')[0])
        visualField = float(re.search(r'([0-9]+)',raySize).group(0))
        Field_50 = abs(x_r_R50)+abs(x_l_R50)
        halfField = 10*visualField/2
        deepth = float(re.search(r'([0-9]+)',conf['deepth']).group(0))
        # float(conf['deepth'][:-2])
        # Dev = (abs(abs(x_r_R50)*(105/(100+deepth/10))-halfField)+abs(abs(x_l_R50)*(105/(100+deepth/10))-halfField))/2
        ssd = float(re.search(r'([0-9]+)',conf['ssd']).group(0))
        Dev = (abs(abs(x_r_R50)*((ssd+5)/(ssd+deepth/10))-halfField)+abs(abs(x_l_R50)*((ssd+5)/(ssd+deepth/10))-halfField))/2
        dm = 0 # 单位cm
        if 1<=visualField<=10:
            dm = 1
        if 10<visualField<=30:
            dm = 0.1*visualField
        if 30<visualField:
            dm = 3
        # 对角线需要*2
        if direction == "AB->GT" or direction == "GT->AB" or direction == "AG->BT" or direction == "BT->AG":
            dm = 2*dm
        # 均整区范围
        visual_xl = -(visualField*10/2-dm*10)
        visual_xr = (visualField*10/2-dm*10)
        uniformArea = []
        for i in range(0, len(x)):
            if visual_xl <= x[i] <=visual_xr:
                uniformArea.append(y[i])
        # 求出均整性(两边视野区域内，最大剂量/最小计量)
        Dmax = max(uniformArea)
        Dmin = min(uniformArea)
        # 辐射区范围
        rayArea = []
        for i in range(0, len(x)):
            if halfField >= abs(x[i]):
                rayArea.append(y[i])
        rayArea_min = min(rayArea)
        # 算出均整度
        flatValue = Dmax/Dmin
        # 均整区对称性
        symmetry = []
        lenth = len(uniformArea)
        for i in range(0,int(lenth/2)):
            l = uniformArea[i]
            r = uniformArea[lenth-1-i]
            if l == 0 or r == 0:
                return
            if l<r:
                symmetry.append(r/l)
            else:
                symmetry.append(l/r)
        # 左边阴影
        left_shadow = abs(abs(x_l_R20)-abs(x_l_R80))
        # 右边阴影
        right_shadow = abs(abs(x_r_R20)-abs(x_r_R80))
        if symmetry:
            sym= max(symmetry)
        else:
            sym= 0
        html = """ <div>
                    <span style="color: #ff0000; font-size: 12pt;float:left">光射野重合性:</span>
                    <span style="color: #000000;font-size: 12pt;text-align:right">%.1fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">均整度:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2f</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">对称性:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2f</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">均整区Dmin:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.3f%%</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">Dmax:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.3f%%</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">左半影:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">右半影:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">均整区:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">(%.1f, %.1f)</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">辐射野Dmin:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.3f%%</span>
                    <br>
                   </div>
                """%(Dev,flatValue,sym,Dmin,Dmax,left_shadow,right_shadow, visual_xl, visual_xr, rayArea_min)
        self.signal_result.emit(html)
        self.result = {
            "x":x,
            "y":y,
            "Dev":Dev,
            "flatValue":flatValue,
            "sym":sym,
            "Dmin":Dmin,
            "left_shadow":left_shadow,
            "right_shadow":right_shadow,
        }
        self.signal_result_update.emit(self.result)

    def getPhotonPdd(self,x,y,raySize):
        ''' 光子-pdd测量结果显示

        x: 坐标系x值(O->G方向上的走位坐标)
        y: 坐标位置对应测量剂量率

        计算结果：
            R100: 100%剂量率位置
            R80: 80%剂量率位置
            R50: 50%剂量率位置
            D0: 0mm深度处剂量率
            D100: 100mm深度处剂量率
            D200: 200mm深度处剂量率
            D200/D100: 200mm深度处剂量率/100mm深度处剂量率
            Enery: 能量
            TPR:
        '''
        # if not isinstance(x, list):
            # return False
        # if not isinstance(y, list):
            # return False
        # max_pos = y.index(max(y))
        try:
            max_pos = np.where(y==max(y))[0][0]
        except:
            return False
        x_r = x[max_pos:]
        y_r = y[max_pos:]
        R100 = x[max_pos]
        R80 = self.linearInterpolation(x_r,y_r,80)
        R50 = self.linearInterpolation(x_r,y_r,50)

        try:
            # D20_idx = np.where(x==200)[0][0]
            # D10_idx = np.where(x==100)[0][0]
            # D0_idx = np.where(x==0)[0][0]
            D200 = y[np.where(x==200)[0][0]]
            D100 = y[np.where(x==100)[0][0]]
            D0 = y[np.where(x==0)[0][0]]
        except:
            return False


        # D200 = y[x.index(200.0)]
        # D100 = y[x.index(100.0)]
        # D0 = y[x.index(0.0)]
        # D20/D10、TPR计算
        try:
            D = D200/(D100)
        except:
            return False
        TPR = 2.189-1.308*(1/D)+0.249*(1/D)*(1/D)
        # 线性差值计算 y = k*x + b
        en = [4,6,8,10,14,16,22,30,50]
        D_list  = np.array([0.54,0.58,0.61,0.63,0.65,0.66,0.68,0.69,0.71])
        energy = self.linearInterpolation(en,D_list,D)

        # 曲线显示
        html = """ <div>
                    <span style="font-size: 12pt;color: #ff0000;float:left">D0:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2f %%</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">D10:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2f %%</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">D20:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2f %%</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">D20/D10:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2f</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">TPR20/10:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2f</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">R_100:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">R_80:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">R_50:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                    <br>
                    <span style="font-size: 12pt;color: #ff0000;float:left">Energy:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2fMeV</span>
                    <br>
                   </div>
                """%(D0,D100,D200,D,TPR,R100,R80,R50,energy)
        self.signal_result.emit(html)
        self.result = {
            "D0":D0,
            "D10":D100,
            "D20":D200,
            "D20_D10":D,
            "TPR":TPR,
            "R100":R100,
            "R80":R80,
            "R50":R50,
            "energy":energy,
            "x":x,
            "y":y,
        }
        self.signal_result_update.emit(self.result)

    def getEbeamPdd(self,x,y,raySize):
        '''电子束-pdd测量结果显示

        x: 坐标系x值(O->G方向上的走位坐标)
        y: 坐标位置对应测量剂量率

        计算结果：
            R100: 100%剂量率位置
            R80: 80%剂量率位置
            R50: 50%剂量率位置
            E0: 能量
            RP:
        '''
        try:
            R100 = x[np.where(y==max(y))[0][0]]
        except:
            return False
        # R100 = x[y.index(max(y))]
        R80 = self.linearInterpolation(x,y,80)
        R50 = self.linearInterpolation(x,y,50)
        E0 = 2.33*R50/10
        # 计算RP
        L_E0 = [1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,50]
        L_RP = [0.505,1.01,1.51,2.02,2.52,3.02,3.52,4.02,4.52,5.02,5.91,6.90,7.89,8.88,9.87,12.3,14.8,19.6,24.6]
        RP = self.linearInterpolation(L_RP,L_E0,E0)
        html = """ <div>
                    <span style="color: #ff0000;font-size: 12pt;float:left">R100:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">R80:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">R50:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">E0:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fMev</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">Rp:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    <br>
                   </div>
                """%(R100,R80,R50,E0,RP)
        self.signal_result.emit(html)
        self.result = {
            "x":x,
            "y":y,
            "R100":R100,
            "R80":R80,
            "R50":R50,
            "E0":E0,
            "RP":RP,
        }
        self.signal_result_update.emit(self.result)

    def getOar(self,x,y,conf):
        # 坐标从负方向排列到正方向
        if x[0] > 0:
            x = x[::-1]
            y = y[::-1]
        # 左半边x,y
        x_l = x[0:int(len(x)/2)]
        y_l = y[0:int(len(y)/2)]
        # 右半边x,y
        x_r = x[int(len(x)/2):]
        y_r = y[int(len(y)/2):]
        # 左边最接近20的y的值
        x_l_R20 = self.linearInterpolation(x_l,y_l,20)
        x_l_R50 = self.linearInterpolation(x_l,y_l,50)
        x_l_R80 = self.linearInterpolation(x_l,y_l,80)
        x_l_R90 = self.linearInterpolation(x_l,y_l,90)
        # 右边最接近20的y的值
        x_r_R20 = self.linearInterpolation(x_r,y_r,20)
        x_r_R50 = self.linearInterpolation(x_r,y_r,50)
        x_r_R80 = self.linearInterpolation(x_r,y_r,80)
        x_r_R90 = self.linearInterpolation(x_r,y_r,90)
        # 最大剂量点和位置
        y_max = max(y)
        x_max = x[np.where(y == y_max)[0][0]]

        raySize = conf['ray_size_x']
        direction = conf['direction']
        visualField = float(re.search(r'([0-9]+)',raySize).group(0))
        Field_50 = abs(x_r_R50)+abs(x_l_R50)
        halfField = 10*visualField/2
        deepth = float(re.search(r'([0-9]+)',conf['deepth']).group(0))
        ssd = float(re.search(r'([0-9]+)',conf['ssd']).group(0))
        ray_type = conf['ray_type']
        standard = conf['standard']
        html = ''
        if standard == "JJG-589-2008":
            if ray_type == "电子":
                # 左半影
                shadow_l = abs(abs(x_l_R20)-abs(x_l_R80))
                # 右半影
                shadow_r = abs(abs(x_r_R20)-abs(x_r_R80))
                # 电子束测量均整区计算
                uniform = (abs(halfField-abs(x_l_R90)) + abs(halfField-abs(x_r_R90))) / 2
                # 电子束对称区域，90%内推1cm
                symmetryArea = []
                if x_l_R90 > 0 and x_r_R90 < 0:
                    n_xl = self.find_nearest(x_l,x_l_R90-10)
                    n_xr = self.find_nearest(x_r,x_r_R90+10)
                    symmetryArea_left = y_l[n_xl:]
                    symmetryArea_right = y_r[:n_xr+1]
                    symmetryArea = np.append(symmetryArea_left, symmetryArea_right)
                if x_l_R90 < 0 and x_r_R90 > 0:
                    n_xl = self.find_nearest(x_l,x_l_R90+10)
                    n_xr = self.find_nearest(x_r,x_r_R90-10)
                    symmetryArea_left = y_l[n_xl:]
                    symmetryArea_right = y_r[:n_xr+1]
                    symmetryArea = np.append(symmetryArea_left, symmetryArea_right)
                if len(symmetryArea) == 0:
                    return False
                dev_list = []
                for i in range(len(symmetryArea)):
                    l = symmetryArea[i]
                    r = symmetryArea[len(symmetryArea)-1-i]
                    if l>r:
                        dev_list.append(l/r)
                    else:
                        dev_list.append(r/l)
                symmetry = max(dev_list)
                # 曲线显示
                html = """ <div>
                            <span style="color: #000000;font-size: 12pt;float:left">均整度:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.3fmm</span>
                            <br>
                            <span style="color: #000000;font-size: 12pt;float:left">对称性:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.3f</span>
                            <br>
                            <span style="color: #ff0000;font-size: 12pt;float:left">左半影:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                            <br>
                            <span style="color: #ff0000;font-size: 12pt;float:left">右半影:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                            <br>
                        </div>
                        """%(uniform, symmetry, shadow_l, shadow_r)
                self.signal_result.emit(html)
                self.result = {
                    "x":x,
                    "y":y,
                    "uniform":uniform,
                    "symmetry":symmetry,
                }
                self.signal_result_update.emit(self.result)
            if ray_type == "光子":
                # 左半影:20%~80%之间的距离
                shadow_l = abs(abs(x_l_R20)-abs(x_l_R80))
                # 右半影:20%~80%之间的距离
                shadow_r = abs(abs(x_r_R20)-abs(x_r_R80))
                # 光射野重合性
                repeatability = (abs(abs(x_r_R50)*((ssd+5)/(ssd+deepth/10))-halfField)+abs(abs(x_l_R50)*((ssd+5)/(ssd+deepth/10))-halfField))/2
                # 均整区
                dm = 0 # 单位cm
                if 1<=visualField<=10:
                    dm = 1
                if 10<visualField<=30:
                    dm = 0.1*visualField
                if 30<visualField:
                    dm = 3
                # 对角线需要*2
                if direction == "AB->GT" or direction == "GT->AB" or direction == "AG->BT" or direction == "BT->AG":
                    dm = 2*dm
                # 均整区范围
                uniformAreaDose = []
                for i in range(0, len(x)):
                    if abs(x[i]) <= abs(visualField*10/2-dm*10):
                        uniformAreaDose.append(y[i])
                # 求出均整性(两边视野区域内，最大剂量/最小计量)
                uniform = max(uniformAreaDose) / min(uniformAreaDose)
                # 对称性:均整区内对称两点的比值（大值除以小值）的最大值
                dev_list = []
                for i in range(len(uniformAreaDose)):
                    l = uniformAreaDose[i]
                    r = uniformAreaDose[len(uniformAreaDose)-1-i]
                    if l>r:
                        dev_list.append(l/r)
                    else:
                        dev_list.append(r/l)
                symmetry = max(dev_list)
                html = """
                    <div>
                        <span style="color: #ff0000; font-size: 12pt;float:left">对称性:</span>
                        <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">左半影:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">右半影:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #ff0000; font-size: 12pt;float:left">均整度:</span>
                        <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">光射野重合性:%.2fmm</span>
                    </div>
                    """%(symmetry,shadow_l,shadow_r,uniform,repeatability)
                self.signal_result.emit(html)
                self.result = {
                    "x":x,
                    "y":y,
                    "symmetry":symmetry,
                    "shadow_l":shadow_l,
                    "shadow_r":shadow_r,
                    "uniform":uniform,
                    "repeatability":repeatability
                }
                self.signal_result_update.emit(self.result)

        if standard == "JJG-1027-2007":
            if ray_type == "Co60":
                # 左半影:20%~80%之间的距离
                shadow_l = abs(abs(x_l_R20)-abs(x_l_R80))
                # 右半影:20%~80%之间的距离
                shadow_r = abs(abs(x_r_R20)-abs(x_r_R80))
                # 对称区: 9x9
                symmetryAreaDose = []
                for i in range(0, len(x)):
                    if abs(x[i]) <= halfField*0.9:
                        symmetryAreaDose.append(y[i])
                # 对称区内比值列表, 大值除以小值
                dev_list = []
                for i in range(len(symmetryAreaDose)):
                    l = symmetryAreaDose[i]
                    r = symmetryAreaDose[len(symmetryAreaDose)-1-i]
                    if l>r:
                        dev_list.append(l/r)
                    else:
                        dev_list.append(r/l)
                # 对称性:对称区内对称两点的比值（大值除以小值）的最大值
                symmetry = max(dev_list)
                # 均整区: 9x9
                uniformAreaDose = []
                for i in range(0, len(x)):
                    if abs(x[i]) <= halfField*0.9:
                        uniformAreaDose.append(y[i])
                # 均整性:均整区内最大剂量除以最小剂量
                uniform = max(uniformAreaDose) / min(uniformAreaDose)
                # 光射野重合性：最大剂量点与最大剂量的50%剂量点的距离减去5cm
                x_l_R50 = self.linearInterpolation(x_l,y_l, y_max*0.5)
                x_r_R50 = self.linearInterpolation(x_r,y_r, y_max*0.5)
                # print('距离')
                # print(x_l_R50)
                # print(x_r_R50)
                repeatability_l = abs(x_max -  x_l_R50) - halfField
                repeatability_r = abs(x_max -  x_r_R50) - halfField
                html = """
                    <div>
                        <span style="color: #ff0000; font-size: 12pt;float:left">辐射野对称性:</span>
                        <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">左半影:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">右半影:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #ff0000; font-size: 12pt;float:left">辐射野均整度:</span>
                        <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">灯光野与照射野重合性</span>
                        <br>
                        <span style="color: #000000;font-size: 12pt;float:right">左偏差:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #000000;font-size: 12pt;float:right">右偏差:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    </div>
                    """%(symmetry,shadow_l,shadow_r,uniform,repeatability_l,repeatability_r)
                self.signal_result.emit(html)
                self.result = {
                    "x":x,
                    "y":y,
                    "symmetry":symmetry,
                    "shadow_l":shadow_l,
                    "shadow_r":shadow_r,
                    "repeatability_l":repeatability_l,
                    "repeatability_r":repeatability_r,
                }
                self.signal_result_update.emit(self.result)

        if standard == "GBZ-161-2004":
            if ray_type == "Co60":
                # 左半影:20%~80%之间的距离
                shadow_l = abs(abs(x_l_R20)-abs(x_l_R80))
                # 右半影:20%~80%之间的距离
                shadow_r = abs(abs(x_r_R20)-abs(x_r_R80))
                # 中心点剂量
                dose_mid = y[int(len(y)/2)]
                # 对称区:射野范围内
                symmetryAreaDose = []
                for i in range(0, len(x)):
                    if abs(x[i]) <= halfField :
                        symmetryAreaDose.append(y[i])
                # 对称区内偏差列表
                err_list = []
                for i in range(len(symmetryAreaDose)):
                    l = i
                    r = len(symmetryAreaDose)-1-i
                    err_list.append(abs(symmetryAreaDose[l] - symmetryAreaDose[r]))
                # 非对称性:对称区内对称两点的差值的最大值除以中心点剂量，百分比表示
                symmetry = (max(err_list) / dose_mid) * 100
                # 均整区:光野边长的80%
                uniformAreaDose = []
                for i in range(0, len(x)):
                    if abs(x[i]) <= halfField*0.8:
                        uniformAreaDose.append(y[i])
                # 均整性:均整区内最大剂量与最小剂量的差值除以中心点剂量，百分比表示
                uniform = (abs(max(uniformAreaDose) - min(uniformAreaDose)) / dose_mid) * 100
                # 光射野重合性：50%剂量点位置与光野5cm的差值
                repeatability_l = abs(abs(x_l_R50) - halfField)
                repeatability_r = abs(abs(x_r_R50) - halfField)
                html = """
                    <div>
                        <span style="color: #ff0000; font-size: 12pt;float:left">照射束内有用射束非对称性:</span>
                        <span style="color: #000000;font-size: 12pt;text-align:right">%.2f%%</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">左半影:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">右半影:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #ff0000; font-size: 12pt;float:left">辐射野均整度:</span>
                        <span style="color: #000000;font-size: 12pt;text-align:right">%.2f</span>
                        <br>
                        <span style="color: #ff0000;font-size: 12pt;float:left">照射野与光野重合度</span>
                        <br>
                        <span style="color: #000000;font-size: 12pt;float:right">左偏差:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                        <br>
                        <span style="color: #000000;font-size: 12pt;float:right">右偏差:</span>
                        <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                    </div>
                    """%(symmetry,shadow_l,shadow_r,uniform,repeatability_l,repeatability_r)
                self.signal_result.emit(html)
                self.result = {
                    "x":x,
                    "y":y,
                    "symmetry":symmetry,
                    "shadow_l":shadow_l,
                    "shadow_r":shadow_r,
                    "repeatability_l":repeatability_l,
                    "repeatability_r":repeatability_r,
                }
                self.signal_result_update.emit(self.result)

    def getPdd(self,x,y,conf):
        ray_type = conf['ray_type']
        standard = conf['standard']
        html = ''
        #  if standard == "JJG-1027-2007":
        #  if standard == "GBZ-161-2004":
        if ray_type == "Co60":
            max_pos = np.where(y==max(y))[0][0]
            R100 = x[max_pos]
            # 曲线显示
            html = """
                <div>
                    <span style="font-size: 12pt;color: #ff0000;float:left">R_100:</span>
                    <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                </div>
                """%(R100)
            self.signal_result.emit(html)
            self.result = {
                "x":x,
                "y":y,
                "R100":R100,
            }
            self.signal_result_update.emit(self.result)
            return
        if standard == "JJG-589-2008":
            if ray_type == "电子":
                R100 = x[np.where(y==max(y))[0][0]]
                R80 = self.linearInterpolation(x,y,80)
                R50 = self.linearInterpolation(x,y,50)
                E0 = 2.33*R50/10
                # 计算RP
                L_E0 = [1,2,3,4,5,6,7,8,9,10,12,14,16,18,20,25,30,40,50]
                L_RP = [0.505,1.01,1.51,2.02,2.52,3.02,3.52,4.02,4.52,5.02,5.91,6.90,7.89,8.88,9.87,12.3,14.8,19.6,24.6]
                RP = self.linearInterpolation(L_RP,L_E0,E0)
                html = """ <div>
                            <span style="color: #ff0000;font-size: 12pt;float:left">R100:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                            <br>
                            <span style="color: #ff0000;font-size: 12pt;float:left">R80:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                            <br>
                            <span style="color: #ff0000;font-size: 12pt;float:left">R50:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fmm</span>
                            <br>
                            <span style="color: #ff0000;font-size: 12pt;float:left">E0:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fMev</span>
                            <br>
                            <span style="color: #ff0000;font-size: 12pt;float:left">Rp:</span>
                            <span style="color: #000000;font-size: 12pt;float:right">%.2fcm</span>
                            <br>
                        </div>
                        """%(R100,R80,R50,E0,RP)
                self.signal_result.emit(html)
                self.result = {
                    "x":x,
                    "y":y,
                    "R100":R100,
                    "R80":R80,
                    "R50":R50,
                    "E0":E0,
                    "RP":RP,
                }
                self.signal_result_update.emit(self.result)
            if ray_type == "光子":
                max_pos = np.where(y==max(y))[0][0]
                x_r = x[max_pos:]
                y_r = y[max_pos:]
                # 最大剂量点位置
                R100 = x[max_pos]
                # 80%剂量点位置
                R80 = self.linearInterpolation(x_r,y_r,80)
                # 50%剂量点位置
                R50 = self.linearInterpolation(x_r,y_r,50)
                # 200mm剂量率
                D200 = y[np.where(x==200)[0][0]]
                # 100mm剂量率
                D100 = y[np.where(x==100)[0][0]]
                D0 = y[np.where(x==0)[0][0]]
                D = D200/(D100)
                TPR = 2.189-1.308*(1/D)+0.249*(1/D)*(1/D)
                # 线性差值计算 y = k*x + b
                en = [4,6,8,10,14,16,22,30,50]
                D_list  = np.array([0.54,0.58,0.61,0.63,0.65,0.66,0.68,0.69,0.71])
                energy = self.linearInterpolation(en,D_list,D)
                # 曲线显示
                html = """ <div>
                            <span style="font-size: 12pt;color: #ff0000;float:left">D0:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2f %%</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">D10:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2f %%</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">D20:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2f %%</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">D20/D10:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2f</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">TPR20/10:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2f</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">R_100:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">R_80:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">R_50:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2fmm</span>
                            <br>
                            <span style="font-size: 12pt;color: #ff0000;float:left">Energy:</span>
                            <span style="font-size: 12pt;color: #000000;float:right">%.2fMeV</span>
                            <br>
                        </div>
                        """%(D0,D100,D200,D,TPR,R100,R80,R50,energy)
                self.signal_result.emit(html)
                self.result = {
                    "D0":D0,
                    "D10":D100,
                    "D20":D200,
                    "D20_D10":D,
                    "TPR":TPR,
                    "R100":R100,
                    "R80":R80,
                    "R50":R50,
                    "energy":energy,
                    "x":x,
                    "y":y,
                }
                self.signal_result_update.emit(self.result)

from ui.chartDeal import Ui_Dialog
import configparser

from ui.chartDealWidget import Ui_MainWindow
class ChartDealWidget(QMainWindow, Ui_MainWindow):
    conf = None
    data = None
    result = None

    def __init__(self, parent=None):
        super(QMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.chart = GraphWindow()
        self.graphWidget = GraphWidget()
        self.table = tabView()
        self.verticalLayout_table.addWidget(self.table)
        # self.label_path = QLabel("文件路径")
        # self.verticalLayout_chart.addWidget(self.label_path)
        # self.verticalLayout_chart.addWidget(self.chart)
        self.verticalLayout_chart.addWidget(self.graphWidget)
        self.graphWidget.signal_result.connect(self.label_result.setText)
        self.graphWidget.signal_result_update.connect(self.updateResult)
        # self.graphWidget.signal_result.connect(self.label_result.setText)
        self.create_toolbar()

    def create_toolbar(self):
        self.exportExcelAct= QAction(QIcon(':icons/images_rc/excel.png'),"&导出excel", triggered=self.exportExcel)
        self.originalAct= QAction(QIcon(':icons/images_rc/line-original.png'),"&原始曲线", triggered=self.graphWidget.lineOriginal)
        self.shiftLeftVal = QDoubleSpinBox()
        self.shiftRightVal = QDoubleSpinBox()
        self.shiftLeftAct= QAction(QIcon(':icons/images_rc/line-shift-left.png'),"&左移", triggered=lambda:self.graphWidget.lineShiftLeft(self.shiftLeftVal.value()))
        self.shiftRightAct= QAction(QIcon(':icons/images_rc/line-shift-right.png'),"&右移", triggered=lambda:self.graphWidget.lineShiftRight(self.shiftRightVal.value()))
        self.smoothAct= QAction(QIcon(':icons/images_rc/line-smooth.png'),"&曲线平滑", triggered=self.graphWidget.lineSmooth)
        self.equidistantVal = QDoubleSpinBox()
        self.equidistantAct= QAction(QIcon(':icons/images_rc/line-smooth.png'),"&线性等距补点", triggered=lambda:self.graphWidget.lineEquidistant(self.equidistantVal.value()))
        # self.symmetryAct= QAction(QIcon(':icons/images_rc/pdd.png'),"&对称", triggered=self.graphWidget.lineSymmetry)
        self.mirrorAct= QAction(QIcon(':icons/images_rc/line-mirror.png'),"&镜像", triggered=self.graphWidget.lineMirror)
        # self.zoomAddAct= QAction(QIcon(':icons/images_rc/line-zoom-add.png'),"&放大", triggered=self.graphWidget.lineZoomAdd)
        # self.zoomDecAct= QAction(QIcon(':icons/images_rc/line-zoom-dec.png'),"&缩小", triggered=self.graphWidget.lineZoomDec)
        # self.zoomOneAct= QAction(QIcon(':icons/images_rc/pdd.png'),"&1:1尺寸", triggered=self.graphWidget.lineZoomOne)
        # self.standardAct= QAction(QIcon(':icons/images_rc/line-mirror.png'),"&标准", triggered=self.graphWidget.lineMirror)

        self.toolbar = self.addToolBar('工具栏')
        self.toolbar.addAction(self.exportExcelAct)
        self.toolbar.addAction(self.originalAct)
        self.toolbar.addAction(self.smoothAct)
        self.toolbar.addAction(self.shiftLeftAct)
        self.toolbar.addWidget(self.shiftLeftVal)
        self.toolbar.addAction(self.shiftRightAct)
        self.toolbar.addWidget(self.shiftRightVal)
        # self.toolbar.addAction(self.symmetryAct)
        self.toolbar.addAction(self.mirrorAct)
        self.toolbar.addAction(self.equidistantAct)
        self.toolbar.addWidget(self.equidistantVal)
        self.toolbar.addWidget(QLabel('选择标准'))
        self.comboBox_standard = QComboBox()
        self.comboBox_standard.addItems([
            'JJG-589-2008',
            'JJG-1027-2007',
            'GBZ-161-2004',
        ])
        self.comboBox_standard.currentIndexChanged.connect(self.updateDeal)
        self.toolbar.addWidget(self.comboBox_standard)

        # self.toolbar.addAction(self.zoomAddAct)
        # self.toolbar.addAction(self.zoomDecAct)
        # self.toolbar.addAction(self.zoomOneAct)

        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

    def updateResult(self, result):
        # print(result)
        self.result = result
        pass

    def read_file(self, file_name=''):
        """读取项目文件中数据

        :param file_name: 文件名
        :return:
        """
        try:
            config = configparser.ConfigParser()
            try:
                config.read(file_name, encoding="utf-8")
            except:
                config.read(file_name, encoding="gb2312")
            condition = dict(config['condition'])
            data = dict(config['data'])
            # 根据键值序号排序
            data_list = [[int(k),data[k]] for k in data.keys()]
            data_list = sorted(data_list)
            # 生成最后数据 [['1','2',],[]]
            data_new = [d[1].replace('[', '').replace(']', '').split(',') for d in data_list]
            return {'condition': condition, 'data': data_new}
        except:
            QMessageBox.information(self, "提示", "文件数据格式错误，无法打开", QMessageBox.Yes)

    def conditionShow(self, conf):
        html = """ <div>
                    <span style="color: #ff0000;font-size: 12pt;float:left">射束类型:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%s</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">能量:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%s</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">源皮距:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%s</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">深度:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%s</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">方向:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%s</span>
                    <br>
                    <span style="color: #ff0000;font-size: 12pt;float:left">射野大小:</span>
                    <span style="color: #000000;font-size: 12pt;float:right">%sx%s</span>
                    <br>
                   </div>
            """ %(conf['ray_type'],conf['power'],conf['ssd'],conf['deepth'],conf['direction'],conf['ray_size_x'],conf['ray_size_y'])
        self.label_condition.setText(html)

    def pddDeal(self):
        data = self.data
        conf = self.conf
        if data:
            x = [float(d[0]) for d in data]
            y = [float(d[1]) for d in data]
            z = [float(d[2]) for d in data]
            tm = [float('%.3f'%float(d[3])) for d in data]
            ts = [float('%.3f'%float(d[4])) for d in data]
            s = '射束类型:%s 能量:%s 源皮距:%s 深度:%s 方向:%s 射野X:%s*%s'%(conf['ray_type'],conf['power'],conf['ssd'],conf['deepth'],conf['direction'],conf['ray_size_x'],conf['ray_size_y'])

            repeat  = [float('%.4f'%(m/(s+0.00000001))) for m,s in zip(tm,ts)]
            normal = [float('%.4f'%(100*r/max(repeat))) for r in repeat]
            # if conf['ray_type'] == '电子':
                # self.chart.getEbeamPdd(z,normal,conf['ray_size_x'])
            # if conf['ray_type'] == '光子':
                # self.chart.getPhotonPdd(z,normal,conf['ray_size_x'])
            self.table.addData([x,y,z,tm,ts,repeat,normal])
            # self.chart.tunnelLine.setTitle(s)
            # self.current_print={'config':conf,'result':self.chart.pdd_result}
            # 赋值给TMR数据
            self.TMR_conf = conf
            self.TMR_x = z
            self.TMR_normal = normal
            self.graphWidget.updatePos(z, normal, conf)
            self.current_print={'config':conf,'result':self.graphWidget.result}

    def oarDeal(self):
        '''oar计算采用左右半边分开进行计算，用于大射野测量造成的左右两边监督通道位置不一样'''
        data = self.data
        conf = self.conf
        if data:
            x = [float(d[0]) for d in data]
            y = [float(d[1]) for d in data]
            z = [float(d[2]) for d in data]
            tm = [float('%.3f'%float(d[3])) for d in data]
            ts = [float('%.3f'%float(d[4])) for d in data]
            s = '射束类型:%s 能量:%s 源皮距:%s 深度:%s 方向:%s 射野X:%s*%s'%(conf['ray_type'],conf['power'],conf['ssd'],conf['deepth'],conf['direction'],conf['ray_size_x'],conf['ray_size_y'])

            if 'merge'  in conf:
                center_pos = int(len(data)/2) + 1
                tm_l = tm[0:center_pos]
                ts_l = ts[0:center_pos]
                repeat_l = [float('%.4f'%(m/(s+0.00000001))) for m,s in zip(tm_l,ts_l)]
                normal_l = [float('%.4f'%(100*r/repeat_l[-1])) for r in repeat_l]

                tm_r = tm[center_pos:]
                ts_r = ts[center_pos:]
                repeat_r= [float('%.4f'%(m/(s+0.00000001))) for m,s in zip(tm_r,ts_r)]
                normal_r= [float('%.4f'%(100*r/repeat_r[0])) for r in repeat_r]

                repeat  = repeat_l + repeat_r
                normal = normal_l + normal_r
            else:
                zero_pos = int(len(data)/2)
                repeat  = [float('%.4f'%(m/(s+0.00000001))) for m,s in zip(tm,ts)]
                normal = [float('%.4f'%(100*r/repeat[zero_pos])) for r in repeat]

            # 方向不同，x对应计算不同
            if 'angle' in conf:
                if conf['angle'] == '0' or conf['angle'] == '180':
                    if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                        x = y
                    else:
                        x = x
                if conf['angle'] == '90' or conf['angle'] == '270':
                    if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                        x = x
                    else:
                        x = y
            else:
                if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                    x = y
            self.table.addData([x,y,z,tm,ts,repeat,normal])
            self.graphWidget.updatePos(x, normal, conf)
            self.current_print={'config':conf,'result':self.graphWidget.result}

    def oarDeal_bk(self):
        '''oar计算采用左右半边分开进行计算，用于大射野测量造成的左右两边监督通道位置不一样'''
        data = self.data
        conf = self.conf
        if data:
            x = [float(d[0]) for d in data]
            y = [float(d[1]) for d in data]
            z = [float(d[2]) for d in data]
            tm = [float('%.3f'%float(d[3])) for d in data]
            ts = [float('%.3f'%float(d[4])) for d in data]
            s = '射束类型:%s 能量:%s 源皮距:%s 深度:%s 方向:%s 射野X:%s*%s'%(conf['ray_type'],conf['power'],conf['ssd'],conf['deepth'],conf['direction'],conf['ray_size_x'],conf['ray_size_y'])

            zero_pos = int(len(data)/2)+1

            tm_l = tm[:zero_pos]
            ts_l = ts[:zero_pos]

            tm_r = tm[zero_pos:]
            ts_r = ts[zero_pos:]

            repeat_l = [float('%.4f'%(m/s)) for m,s in zip(tm_l,ts_l)]
            repeat_r = [float('%.4f'%(m/s)) for m,s in zip(tm_r,ts_r)]

            # repeat  = [float('%.4f'%(m/s)) for m,s in zip(tm,ts)]
            repeat  = repeat_l + repeat_r
            # 中心点位置进行归一化

            left_data = repeat[:zero_pos]
            normal_l = [float('%.4f'%(100*r/repeat_l[len(repeat_l)-1])) for r in repeat_l]

            right_data = repeat[zero_pos:]
            normal_r = [float('%.4f'%(100*r/repeat_r[0])) for r in repeat_r]

            # normal = [float('%.4f'%(100*r/repeat[zero_pos])) for r in repeat]
            normal = normal_l + normal_r
            # try:
            #  angle = conf['angle'] if 'angle' in conf else ''
            # 方向不同，x对应计算不同
            if 'angle' in conf:
                if conf['angle'] == '0' or conf['angle'] == '180':
                    if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                        x = y
                    else:
                        x = x
                if conf['angle'] == '90' or conf['angle'] == '270':
                    if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                        x = x
                    else:
                        x = y
            else:
                if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                    x = y
            # 区分电子和光子计算
            # if conf['ray_type'] == '电子':
                # self.chart.getEbeamOar(x,normal,conf['ray_size_x'])
            # if conf['ray_type'] == '光子':
                # self.chart.getPhotonOar(x,normal,conf)
            # self.chart.tunnelLine.setTitle(s)
            self.table.addData([x,y,z,tm,ts,repeat,normal])
            self.graphWidget.updatePos(x, normal, conf)
            self.current_print={'config':conf,'result':self.graphWidget.result}

    def updateDeal(self):
        # 将用户选择的标准添加进配置里面
        self.label_result.setText('')
        self.conf['standard'] = self.comboBox_standard.currentText()
        self.conditionShow(self.conf)
        if self.conf['type'] == 'PDD':
            self.pddDeal()
        if self.conf['type'] == 'OAR':
            self.oarDeal()

    def showOneLine(self, file_path):
        res = self.read_file(file_name=file_path)
        conf = res['condition']
        data = res['data']
        self.conf = conf
        self.data = data
        try:
            self.updateDeal()
        except:
            QMessageBox.information(self, "提示", "文件数据格式错误，无法打开", QMessageBox.Yes)

    def showOneLine_bk(self, file_path):
        try:
            self.label_path.setText("文件路径："+file_path)
            res = self.read_file(file_name=file_path)
            conf = res['condition']
            self.conditionShow(conf)
            data = res['data']
            x = [float(d[0]) for d in data]
            y = [float(d[1]) for d in data]
            z = [float(d[2]) for d in data]
            tm = [float('%.3f'%float(d[3])) for d in data]
            ts = [float('%.3f'%float(d[4])) for d in data]
            s = '射束类型:%s 能量:%s 源皮距:%s 深度:%s 方向:%s 射野X:%s*%s'%(conf['ray_type'],conf['power'],conf['ssd'],conf['deepth'],conf['direction'],conf['ray_size_x'],conf['ray_size_y'])
            if conf['type'] == 'PDD':
                repeat  = [float('%.4f'%(m/(s+0.00000001))) for m,s in zip(tm,ts)]
                normal = [float('%.4f'%(100*r/max(repeat))) for r in repeat]
                if conf['ray_type'] == '电子':
                    self.chart.getEbeamPdd(z,normal,conf['ray_size_x'])
                if conf['ray_type'] == '光子':
                    self.chart.getPhotonPdd(z,normal,conf['ray_size_x'])
                self.table.addData([x,y,z,tm,ts,repeat,normal])
                self.chart.tunnelLine.setTitle(s)
                self.current_print={'config':conf,'result':self.chart.pdd_result}
                # 赋值给TMR数据
                self.TMR_conf = conf
                self.TMR_x = z
                self.TMR_normal = normal
                self.graphWidget.updatePos(z, normal)
            if conf['type'] == 'OAR':
                # oar计算采用左右半边分开进行计算，用于大射野测量造成的左右两边监督通道位置不一样
                zero_pos = int(len(data)/2)+1

                tm_l = tm[:zero_pos]
                ts_l = ts[:zero_pos]

                tm_r = tm[zero_pos:]
                ts_r = ts[zero_pos:]

                repeat_l = [float('%.4f'%(m/s)) for m,s in zip(tm_l,ts_l)]
                repeat_r = [float('%.4f'%(m/s)) for m,s in zip(tm_r,ts_r)]

                # repeat  = [float('%.4f'%(m/s)) for m,s in zip(tm,ts)]
                repeat  = repeat_l + repeat_r
                # 中心点位置进行归一化

                left_data = repeat[:zero_pos]
                normal_l = [float('%.4f'%(100*r/repeat_l[len(repeat_l)-1])) for r in repeat_l]

                right_data = repeat[zero_pos:]
                normal_r = [float('%.4f'%(100*r/repeat_r[0])) for r in repeat_r]

                # normal = [float('%.4f'%(100*r/repeat[zero_pos])) for r in repeat]
                normal = normal_l + normal_r
                # try:
                self.table.addData([x,y,z,tm,ts,repeat,normal])
                #  angle = conf['angle'] if 'angle' in conf else ''
                # 方向不同，x对应计算不同
                if 'angle' in conf:
                    if conf['angle'] == '0' or conf['angle'] == '180':
                        if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                            x = y
                        else:
                            x = x
                    if conf['angle'] == '90' or conf['angle'] == '270':
                        if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                            x = x
                        else:
                            x = y
                else:
                    if conf['direction'] == 'G->T' or conf['direction'] == 'T->G':
                        x = y
                # 区分电子和光子计算
                if conf['ray_type'] == '电子':
                    self.chart.getEbeamOar(x,normal,conf['ray_size_x'])
                if conf['ray_type'] == '光子':
                    self.chart.getPhotonOar(x,normal,conf)
                self.chart.tunnelLine.setTitle(s)
                self.current_print={'config':conf,'result':self.chart.oar_result}
                self.graphWidget.updatePos(x, normal)
        except:
            QMessageBox.information(self,'提示','当前文件测量数据异常，无法显示！',QMessageBox.Yes)

    def exportExcel(self):
        # print("*"*10)
        # print(self.current_print)
        try:
            conf = self.current_print['config']
            _time      = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            standard   = str(conf["standard"])
            time_pre   = str(conf["time"])
            Type       = str(conf["type"])
            ray_type   = str(conf["ray_type"])
            ray_size_x = str(conf["ray_size_x"])
            ray_size_y = str(conf["ray_size_y"])
            power      = str(conf["power"])
            ssd        = str(conf["ssd"])
            direction  = str(conf["direction"])
            deepth     = str(conf["deepth"])
            # result     = self.current_print['result']
            result = self.result
            name_time  = time.strftime("%Y%m%d%H%M%S", time.localtime())
            f = QFileDialog.getSaveFileName(self,
                                            "导出Excel",
                                            '%s/data/%s'%(os.getcwd(),name_time+'_'+'_'+Type+'_'+ray_type+'_'+power+'_'+direction.replace('->','')+'_'+ray_size_x+'x'+ray_size_y),'Excel Files(*.xls)')
            if f[0]:
                filename = f[0]
                wb = xlsxwriter.Workbook(filename)
                ws = wb.add_worksheet()
                if standard == "JJG-589-2008":
                    if conf['type'] == "PDD" and conf['ray_type'] == "光子":
                        ws.write(0, 3, "PDD测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,4,"D0")
                        ws.write(2,4,"D10")
                        ws.write(3,4,"D20")
                        ws.write(4,4,"D20_D10")
                        ws.write(5,4,"R100")
                        ws.write(6,4,"R80")
                        ws.write(7,4,"R50")
                        ws.write(8,4,"Energy")

                        ws.write(1,5,"%.2f %%"%(result["D0"]))
                        ws.write(2,5,"%.2f %%"%(result["D10"]))
                        ws.write(3,5,"%.2f %%"%(result["D20"]))
                        ws.write(4,5,"%.2f   "%(result["D20_D10"]))
                        ws.write(5,5,"%.2f   "%(result["R100"]))
                        ws.write(6,5,"%.2f mm"%(result["R80"]))
                        ws.write(7,5,"%.2f mm"%(result["R50"]))
                        ws.write(8,5,"%.2f MeV"%(result["energy"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                    if conf['type'] == "PDD" and conf['ray_type'] == "电子":
                        ws.write(0, 3, "EBEAM测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,3,"R100")
                        ws.write(2,3,"R80")
                        ws.write(3,3,"R50")
                        ws.write(4,3,"E0")
                        ws.write(5,3,"RP")
                        ws.write(1,4,"%.2f %%"%(result["R100"]))
                        ws.write(2,4,"%.2f %%"%(result["R80"]))
                        ws.write(3,4,"%.2f %%"%(result["R50"]))
                        ws.write(4,4,"%.2f %%"%(result["E0"]))
                        ws.write(5,4,"%.2f"%(result["RP"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                    if conf['type'] == "OAR" and conf['ray_type'] == "光子":
                        ws.write(0, 3, "OAR测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,4,"光射野重合性")
                        ws.write(2,4,"均整度")
                        ws.write(3,4,"对称性")
                        ws.write(5,4,"左半影")
                        ws.write(6,4,"右半影")
                        ws.write(1,5,"%.1fmm"%(result["repeatability"]))
                        ws.write(2,5,"%.2f "%(result["uniform"]))
                        ws.write(3,5,"%.2f "%(result["symmetry"]))
                        ws.write(5,5,"%.2f"%(result["shadow_l"]))
                        ws.write(6,5,"%.2f"%(result["shadow_r"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                    if conf['type'] == "OAR" and conf['ray_type'] == "电子":
                        ws.write(0, 3, "OAR测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(2,4,"均整度")
                        ws.write(3,4,"对称性")
                        ws.write(1,5,"%.1f mm"%(result["uniform"]))
                        ws.write(2,5,"%.2f %%"%(result["symmetry"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                wb.close()
                QMessageBox.warning(self,'提示','导出成功!\r\n%s'%filename,QMessageBox.Yes)
        except Exception as e:
            QMessageBox.information(self,'警告','%s'%e,QMessageBox.Yes)

    def getExcel(self, file):
        try:
            conf = self.current_print['config']
            _time      = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            standard   = str(conf["standard"])
            time_pre   = str(conf["time"])
            Type       = str(conf["type"])
            ray_type   = str(conf["ray_type"])
            ray_size_x = str(conf["ray_size_x"])
            ray_size_y = str(conf["ray_size_y"])
            power      = str(conf["power"])
            ssd        = str(conf["ssd"])
            direction  = str(conf["direction"])
            deepth     = str(conf["deepth"])
            result     = self.current_print['result']
            name_time  = time.strftime("%Y%m%d%H%M%S", time.localtime())
            if file:
                filename = file
                wb = xlsxwriter.Workbook(filename)
                ws = wb.add_worksheet()
                if standard == "JJG-589-2008":
                    if conf['type'] == "PDD" and conf['ray_type'] == "光子":
                        ws.write(0, 3, "PDD测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,4,"D0")
                        ws.write(2,4,"D10")
                        ws.write(3,4,"D20")
                        ws.write(4,4,"D20_D10")
                        ws.write(5,4,"R100")
                        ws.write(6,4,"R80")
                        ws.write(7,4,"R50")
                        ws.write(8,4,"Energy")

                        ws.write(1,5,"%.2f %%"%(result["D0"]))
                        ws.write(2,5,"%.2f %%"%(result["D10"]))
                        ws.write(3,5,"%.2f %%"%(result["D20"]))
                        ws.write(4,5,"%.2f   "%(result["D20_D10"]))
                        ws.write(5,5,"%.2f   "%(result["R100"]))
                        ws.write(6,5,"%.2f mm"%(result["R80"]))
                        ws.write(7,5,"%.2f mm"%(result["R50"]))
                        ws.write(8,5,"%.2f MeV"%(result["energy"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                    if conf['type'] == "PDD" and conf['ray_type'] == "电子":
                        ws.write(0, 3, "EBEAM测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,3,"R100")
                        ws.write(2,3,"R80")
                        ws.write(3,3,"R50")
                        ws.write(4,3,"E0")
                        ws.write(5,3,"RP")
                        ws.write(1,4,"%.2f %%"%(result["R100"]))
                        ws.write(2,4,"%.2f %%"%(result["R80"]))
                        ws.write(3,4,"%.2f %%"%(result["R50"]))
                        ws.write(4,4,"%.2f %%"%(result["E0"]))
                        ws.write(5,4,"%.2f"%(result["RP"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                    if conf['type'] == "OAR" and conf['ray_type'] == "光子":
                        ws.write(0, 3, "OAR测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,4,"光射野重合性")
                        ws.write(2,4,"均整度")
                        ws.write(3,4,"对称性")
                        ws.write(5,4,"左半影")
                        ws.write(6,4,"右半影")
                        ws.write(1,5,"%.1fmm"%(result["repeatability"]))
                        ws.write(2,5,"%.2f "%(result["uniform"]))
                        ws.write(3,5,"%.2f "%(result["symmetry"]))
                        ws.write(5,5,"%.2f"%(result["shadow_l"]))
                        ws.write(6,5,"%.2f"%(result["shadow_r"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                    if conf['type'] == "OAR" and conf['ray_type'] == "电子":
                        ws.write(0, 3, "OAR测量数据结果")
                        ws.write(1, 1, "D(mm)")
                        ws.write(1, 2, "Q(%)")
                        data = [[x,y] for x,y in zip(result["x"],result["y"])]
                        for i in range(0,len(data)):
                            ws.write(i+2,1,str(data[i][0]))
                            ws.write(i+2,2,str(data[i][1]))

                        ws.write(1,4,"均整度")
                        ws.write(2,4,"对称性")
                        ws.write(1,5,"%.1f mm"%(result["uniform"]))
                        ws.write(2,5,"%.2f %%"%(result["symmetry"]))

                        ws.write(1,7,"射束类型")
                        ws.write(2,7,"能量")
                        ws.write(3,7,"源皮距")
                        ws.write(4,7,"方向")
                        ws.write(5,7,"深度")

                        ws.write(1,8,ray_type)
                        ws.write(2,8,power)
                        ws.write(3,8,ssd)
                        ws.write(4,8,direction)
                        ws.write(5,8,deepth)

                        ws.write(1,10,"打印时间")
                        ws.write(2,10,"测量日期")

                        ws.write(1,11,_time)
                        ws.write(2,11,time_pre)

                        savePath= r'%s\data\temp.png'%os.getcwd()
                        pm = self.graphWidget.grab()
                        pm.save(savePath)
                        ws.insert_image("E12",savePath)
                wb.close()
        except Exception as e:
            QMessageBox.information(self,'警告','%s'%e,QMessageBox.Yes)

    def exportBrowser(self):
        import webbrowser
        webbrowser.open(os.getcwd()+'/test.doc')
        pass

    def exportWord(self):
        try:
            from docx import Document
            from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
            from docx.shared import Inches
            from docx.shared import RGBColor
            from docx.shared import Pt
            import time
            document = Document()
            content = self.current_print
            result = content['result']
            conf = content['config']
            _time     = ": "+ time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
            time_pre  = ": " + str(conf["time"])
            _type      = ": " + str(conf["type"])
            ray_type   = ": " + str(conf["ray_type"])
            ray_size_x = ": " + str(conf["ray_size_x"])
            ray_size_y = ": " + str(conf["ray_size_y"])
            power     = ": " + str(conf["power"])
            ssd       = ": " + str(conf["ssd"])
            direction = ": " + str(conf["direction"])
            deepth    = ": " + str(conf["deepth"])
            # name      = ": " + str(conf["name"])
            # room      = ": " + str(conf["room"])
            result    = self.current_print['result']

            name_time  = time.strftime("%H%M%S", time.localtime())
            file_name = '%s_%s_%s_%s_%s_%s'%(_type,ray_type,power,direction.replace('->',''),ray_size_x+'x'+ray_size_y,name_time)
            f = QFileDialog.getSaveFileName(self,
                                            "导出word",
                                            '%s/data/%s'%(os.getcwd(),file_name.replace(': ','')),
                                            'Word Files(*.doc)')
            if f[0]:
                def get_format(s1, s2, s3, s4, s5, s6):
                    return "{0:{6}<4}{1:{6}<6}\t{2:{6}<5}{3:{6}<12}\t{4:{6}<6}{5:{6}<4}".format(s1, s2, s3, s4, s5, s6, chr(12288))

                if conf['type'] == "PDD":
                    if conf['ray_type'] == '光子':
                        document.add_heading('PDD测量数据结果分析', 0)
                        D0 = ": " + "%.2f %%" % (result["D0"])
                        D10 = ": " + "%.2f %%" % (result["D10"])
                        D20 = ": " + "%.2f %%" % (result["D20"])
                        D20_D10 = ": " + "%.2f   " % (result["D20_D10"])
                        R_max = ": " + "%.2f   " % (result["R100"])
                        R_80 = ": " + "%.2f mm" % (result["R80"])
                        R_50 = ": " + "%.2f mm" % (result["R50"])
                        Enery = ": " + "%.2f MeV" % (result["energy"])
                        orderItems = [[x, y] for x, y in zip(result["x"], result["y"])]
                        document.add_paragraph(get_format("射束类型", ray_type, "D0", D0, "打印时间", _time))
                        document.add_paragraph(get_format("能量", power, "D10", D10, "测量日期", time_pre))
                        document.add_paragraph(get_format("源皮距", ssd, "D20", D20, "", ""))
                        document.add_paragraph(get_format("方向", direction, "D20/D10", D20_D10, "", ""))
                        document.add_paragraph(get_format("深度", deepth, "R_max", R_max, "", ""))
                        document.add_paragraph(get_format("", "", "R_80", R_80, '', ''))
                        document.add_paragraph(get_format("", "", "R_50", R_50, '', ''))
                        document.add_paragraph(get_format("", "", "Enery", Enery, '', ''))
                    if conf['ray_type'] == '电子':
                        pass

                if conf['type'] == "OAR":
                    document.add_heading('OAR测量数据结果', 0)
                    if conf['ray_type'] == '光子':
                        Dev = " : " + "%.2f %%" % (result["Dev"])
                        flatValue = " : " + "%.2f %%" % (result["flatValue"])
                        sym = " : " + "%.2f %%" % (result["sym"])
                        Dmin = " : " + "%.2f %%" % (result["Dmin"])
                        left_shadow = " : " + "%.2f" % (result["left_shadow"])
                        right_shadow = " : " + "%.2f" % (result["right_shadow"])
                        orderItems = [[x, y] for x, y in zip(result["x"], result["y"])]

                        document.add_paragraph(get_format("射束类型", ray_type, "光野重合性", Dev, "打印时间:", _time))
                        document.add_paragraph(get_format("能量", power, "均整度", flatValue, "测量日期:", time_pre))
                        document.add_paragraph(get_format("源皮距", ssd, "对称性", sym, "", ""))
                        document.add_paragraph(get_format("方向", direction, "最小剂量率", Dmin, "", ""))
                        document.add_paragraph(get_format("深度", deepth, "左半影", left_shadow, '', ''))
                        document.add_paragraph(get_format("  ", "  ", "右半影", right_shadow, '', ''))
                    if conf['ray_type'] == '电子':
                        pass

                # 添加图片，居中
                document.add_picture('temp.png', width=Inches(5.25))
                last_paragraph = document.paragraphs[-1]
                last_paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

                def add_result_table(result):
                    col_ = 10
                    table_res = document.add_table(rows=0, cols=col_+1)
                    for i in range(0, len(result['x'])):
                        if i % col_ == 0:
                            def add_p_run(s,c):
                                run = p.add_run(s)  # 把表头放在一个数组里面的，这样方便赋值
                                run.font.color.rgb = c  # 颜色设置，这里是用RGB颜色
                                run.font.size = Pt(8)  # 字体大小设置，和word里面的字号相对应
                            row_cells = table_res.add_row().cells
                            p = row_cells[0].paragraphs[0]  # 利用段落功能添加文字
                            add_p_run('x(mm)',RGBColor(54, 95, 145))
                            x = result['x'][i:i + col_]
                            for c in range(0, len(x)):
                                p = row_cells[c + 1].paragraphs[0]  # 利用段落功能添加文字
                                add_p_run(str(x[c]),RGBColor(54, 95, 145))
                            row_cells = table_res.add_row().cells
                            p = row_cells[0].paragraphs[0]  # 利用段落功能添加文字
                            add_p_run('Q(%)',RGBColor(254, 95, 145))
                            y = result['y'][i:i + col_]
                            for c in range(0, len(y)):
                                p = row_cells[c + 1].paragraphs[0]  # 利用段落功能添加文字
                                add_p_run(str(y[c]),RGBColor(254, 95, 145))
                add_result_table(result)
                document.save(f[0])
                QMessageBox.warning(self,'提示','导出成功!\r\n%s'%f[0],QMessageBox.Yes)
        except Exception as e:
            QMessageBox.information(self,'警告','%s'%e,QMessageBox.Yes)

    def exportMultiExcel(self, files=[]):
        if files:
            exp_dir = QFileDialog.getExistingDirectory(self,
                                        "请选择数据导出路径!",
                                        '%s/data'%os.getcwd())
            if exp_dir:
                msgBox = QMessageBox()
                msgBox.setWindowTitle('正在导出Excel中....')
                msgBox.show()
                for f in files:
                    if f.endswith('.d'):
                        try:
                            file_name = f.split("data/")[1]
                            xls_file = exp_dir+'/'+file_name.replace('.d','.xls')
                            self.showOneLine(f)
                            print(xls_file)
                            self.getExcel(xls_file.replace('/','\\'))
                        except:
                            QMessageBox.information(self,'提示','导出[%s]失败！'%f,QMessageBox.Yes)
                QMessageBox.information(self,'提示','导出成功！',QMessageBox.Yes)
        else:
            QMessageBox.warning(self,'提示','未选择要导出的文件！',QMessageBox.Yes)

    def printer(self):
        "动作二：打印，有预览"
        if not self.current_print:
            QMessageBox.warning(self,'警告','请选择要打印的数据!',QMessageBox.Yes)
            return
        dialog = QPrintPreviewDialog()
        w = QApplication.desktop().screenGeometry().width()
        h = QApplication.desktop().screenGeometry().height()
        dialog.setFixedSize(w/2,h*3/4)
        dialog.paintRequested.connect(self.handlePaintRequest)
        dialog.exec_()

    def handlePaintRequest(self, printer):
        """打印函数"""
        document = QTextDocument()
        cursor = QTextCursor(document)
        cursor.movePosition(QTextCursor.Start)
        # 框架
        topFrame = cursor.currentFrame()
        topFrameFormat = topFrame.frameFormat()
        topFrameFormat.setPadding(16)
        topFrame.setFrameFormat(topFrameFormat)
        # 文本框架
        textFormat = QTextCharFormat()
        # 文本字体加粗框架
        boldFormat = QTextCharFormat()
        boldFormat.setFontWeight(QFont.Bold)
        conf = self.current_print['config']
        _time     = ": "+ time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        time_pre  = ": " + str(conf["time"])
        ray_type   = ": " + str(conf["ray_type"])
        power     = ": " + str(conf["power"])
        ssd       = ": " + str(conf["ssd"])
        direction = ": " + str(conf["direction"])
        deepth    = ": " + str(conf["deepth"])
        # name      = ": " + str(conf["name"])
        # room      = ": " + str(conf["room"])
        result    = self.current_print['result']
        if conf['type'] == "PDD":
            cursor.insertText("\t\t\t\t%-8s"%("PDD测量数据结果"),boldFormat)
            cursor.insertBlock()
            cursor.insertBlock()
            D0        = ": " + "%.2f %%"%(result["D0"])
            D10       = ": " + "%.2f %%"%(result["D10"])
            D20       = ": " + "%.2f %%"%(result["D20"])
            D20_D10   = ": " + "%.2f   "%(result["D20_D10"])
            R_max     = ": " + "%.2f   "%(result["R100"])
            R_80      = ": " + "%.2f mm"%(result["R80"])
            R_50      = ": " + "%.2f mm"%(result["R50"])
            Enery     = ": " + "%.2f MeV"%(result["energy"])
            orderItems = [[x,y] for x,y in zip(result["x"],result["y"])]
            cursor.insertText("%-8s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("射束类型",ray_type,"D0",D0,"打印时间",_time),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("能量",power,"D10",D10,"测量日期",time_pre),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-9s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("源皮距",ssd,"D20",D20,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("方向",direction,"D20/D10",D20_D10,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("深度",deepth,"R_max",R_max,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("","","R_80",R_80,'',''),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("","","R_50",R_50,'',''),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("","","Enery",Enery,'',''),textFormat)
        if conf['type'] == "OAR":
            cursor.insertText("\t\t\t\t%-8s"%("OAR测量数据结果"),boldFormat)
            cursor.insertBlock()
            cursor.insertBlock()
            Dev          = ": " + "%.2f %%"%(result["Dev"])
            flatValue    = ": " + "%.2f %%"%(result["flatValue"])
            sym          = ": " + "%.2f %%"%(result["sym"])
            Dmin         = ": " + "%.2f %%"%(result["Dmin"])
            left_shadow  = ": " + "%.2f"%(result["left_shadow"])
            right_shadow = ": " + "%.2f"%(result["right_shadow"])
            orderItems   = [[x,y] for x,y in zip(result["x"],result["y"])]
            cursor.insertText("%-8s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("射束类型",ray_type,"光野重合性",Dev,"打印时间",_time),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("能量",power,"均整度",flatValue,"测量日期",time_pre),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-9s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("源皮距",ssd,"对称性",sym,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("方向",direction,"最小剂量率",Dmin,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("深度",deepth,"左半影",left_shadow,'',''),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("","","右半影",right_shadow,'',''),textFormat)
        if conf['type'] == "EBEAM":
            cursor.insertText("\t\t\t\t%-8s"%("EBEAM测量数据结果"),boldFormat)
            cursor.insertBlock()
            cursor.insertBlock()
            R100      = ": " + "%.2f %%"%(result["R100"])
            R80       = ": " + "%.2f %%"%(result["R80"])
            R50       = ": " + "%.2f %%"%(result["R50"])
            E0        = ": " + "%.2f %%"%(result["E0"])
            RP        = ": " + "%.2f"%(result["RP"])
            orderItems   = [[x,y] for x,y in zip(result["x"],result["y"])]
            cursor.insertText("%-8s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("射束类型",ray_type,"R100",R100,"打印时间",_time),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("能量",power,"R80",R80,"测量日期",time_pre),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-9s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("源皮距",ssd,"R50",R50,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("方向",direction,"E0",E0,"",""),textFormat)
            cursor.insertBlock()
            cursor.insertText("%-10s%-8s\t%-6s\t%-10s\t%-4s\t%-8s"%("深度",deepth,"RP",RP,'',''),textFormat)

        cursor.setPosition(topFrame.lastPosition())
        cursor.insertBlock()

        bodyFrameFormat = QTextFrameFormat()
        bodyFrameFormat.setWidth(QTextLength(QTextLength.PercentageLength, 100))
        cursor.insertFrame(bodyFrameFormat)

        # 数据总数
        _len = len(orderItems)
        # 显示行数
        num = 21
        # 显示列数
        col = _len//num + 1
        # 列数中包含多少列
        col_col = 2
        orderTableFormat = QTextTableFormat()
        orderTableFormat.setAlignment(Qt.AlignLeft)
        orderTable = cursor.insertTable(1, col*col_col, orderTableFormat)

        orderFrameFormat = cursor.currentFrame().frameFormat()
        orderFrameFormat.setBorder(1)
        cursor.currentFrame().setFrameFormat(orderFrameFormat)

        # 创建表格头显示
        for i in range(col):
            cursor = orderTable.cellAt(0, i*col_col+0).firstCursorPosition()
            cursor.insertText("D(mm)", boldFormat)
            cursor = orderTable.cellAt(0, i*col_col+1).firstCursorPosition()
            cursor.insertText("Q(%)", boldFormat)
        # 插入数据
        for j in range(num):
            row = orderTable.rows()
            orderTable.insertRows(row, 1)
            item = orderItems[j]
            for c in range(col_col):
                cursor = orderTable.cellAt(row, c).firstCursorPosition()
                cursor.insertText(str(item[c]), textFormat)
            for i in range(1, col):
                if (i*num+j) < _len:
                    item = orderItems[i*num+j]
                    for c in range(col_col):
                        cursor = orderTable.cellAt(row, i*col_col+c).firstCursorPosition()
                        cursor.insertText(str(item[c]), textFormat)
        cursor.setPosition(topFrame.lastPosition())
        cursor.insertBlock()

        srcPath = os.getcwd() + '\\temp.png'
        savePath = os.getcwd() + '\\temp_small.png'
        pm = self.chart.grab();
        pm.save(srcPath)
        img = Image.open(srcPath)
        w, h = img.size
        img.resize((int(w*2/3), int(h*2/3)),Image.ANTIALIAS).save(savePath, "png")

        fragment = QTextDocumentFragment()
        fragment = QTextDocumentFragment.fromHtml("<img src='%s'>"%savePath)
        cursor.insertFragment(fragment)

        print(printer)
        document.print(printer)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    window = ChartDealWidget()
    window.show()
    window.resize(1266, 768)
    app.exec_()

